【发布时间】:2020-01-30 17:31:41
【问题描述】:
据我所知,我们永远不应该使用关系运算符来比较两个 const 字符串 <>... 因为它比较的是地址而不是值:
const char* sz1 = "Hello";
const char* sz2 = "hello";
if(sz1 < sz2);// not valid. So use strcmp instead.
- 我注意到像
map, multimap, set, multiset这样的有序关联容器对其key施加了限制,因此应该比较键以对容器中的元素进行排序。键的默认运算符是<运算符。
一切都很清楚,直到我创建了 map, set 的 const char* 然后我得到的结果不正确:
std::set<const char*> scp{ "Hello", "World", "C++", "Programming" };
std::set<std::string> sstr{ "Hello", "World", "C++", "Programming" };
// error
std::copy(scp.cbegin(), scp.cend(), std::ostream_iterator<const char*>(std::cout, " "));
std::cout << std::endl;
// Ok
std::copy(sstr.cbegin(), sstr.cend(), std::ostream_iterator<std::string>(std::cout, " "));
std::cout << std::endl;
很明显,
scp将指针与字符串进行比较,而sstr可以,只要string类定义了<以正常工作。为什么 STL 允许这样做? (创建关键元素类型为
char*的关联容器)为什么这里甚至没有警告?
【问题讨论】:
-
反论点:为什么要使用 可能 指向 C 样式字符串的指针来阻止标准容器,因为您不应该使用 C 样式C++ 中的字符串?
-
仅仅因为它不适用于这种简单的情况并不意味着其他人不会有一个用例,其中指针作为键可能没有用。此外,您的情况可以通过提供您自己的使用
strcmp的比较功能来解决。 -
我什至认为
sz1 < sz2是UB(而std::less<>{}(sz1, sz2)不是)。 -
@Jarod42 除非它们指向同一个数组,是的。
-
您可能只想比较指针。为什么禁止这样做(即使不寻常)?对于警告,表达比较指针意图的正确方法是什么?