[英]can `operator<` of some type have different definitions between compilation units?
I wanted to create a std::set<X>
, for a pod struct, X
.我想为 pod 结构X
创建一个std::set<X>
。 I tried providing a free operator<
.我尝试提供免费的operator<
。 I did not want this operator to have a global effect (outside this compilation unit), so I set the operator<
as static .我不希望此运算符具有全局效果(在此编译单元之外),因此我将operator<
设置为static 。 ( link to code ) (链接到代码)
struct X { int value; };
static bool operator< (const X& a, const X& b) { return a.value < b.value; }
void foo() {
std::set<X> some_set;
some_set.insert({1});
}
This compiles fine.这编译得很好。
However, if I move the operator<
in an unnamed namespace ( link to code )但是,如果我将operator<
移动到未命名的命名空间中(链接到代码)
struct X { int value; };
namespace {
bool operator< (const X& a, const X& b) { return a.value < b.value; }
}
void foo() {
std::set<X> some_set;
some_set.insert({1});
}
which should be equivalent,这应该是等价的,
then std::less<X>
complains:然后std::less<X>
抱怨:
usr/local/include/c++/12.1.0/bits/stl_function.h:408:20: error: no match for 'operator<' (operand types are 'const X' and 'const X')
{ return __x < __y; }
Okay, I could have used a custom comparator instead.好的,我本可以改用自定义比较器。
But can anybody explain why the above does not work?但是有人能解释为什么上面的方法不起作用吗? In general, is it possible to provide a different operator implementation in compilation units of the same struct?一般来说,是否可以在同一结构的编译单元中提供不同的运算符实现?
This boils down to following:这归结为以下几点:
#include <iostream>
struct A {};
namespace
{
void foo(A) {} // Your `operator<`.
}
namespace N
{
void foo(int) {} // Some random `operator<` in `std`.
template <typename T>
void bar(T value)
{
foo(value);
}
}
int main()
{
N::bar(A{});
}
This doesn't work because N::foo
shadows foo(A)
in the unnamed namespace.这不起作用,因为N::foo
隐藏了未命名命名空间中的foo(A)
。
If there was no unnamed namespace, foo(A)
would instead be found via ADL , because it would be in the same namespace as A
.如果没有未命名的命名空间,则foo(A)
将改为通过ADL找到,因为它与A
位于同一命名空间中。
Also note that this appears to violate one-definition rule.另请注意,这似乎违反了单一定义规则。 While your operator<
is static
, std::less
is not, and its instantiations in different translation units will pick different operator<
s, which appears to be illegal.虽然您的operator<
是static
,但std::less
不是,并且它在不同翻译单元中的实例化将选择不同的operator<
s,这似乎是非法的。
This could cause one of our operator<
s to be used in every TU, when inline implementations of std::less
from different TUs are ultimately merged by the linker.当来自不同 TU 的std::less
的内联实现最终被 linker 合并时,这可能会导致我们的一个operator<
被用于每个 TU。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.