简体   繁体   English

某种类型的 operator< 可以在编译单元之间有不同的定义吗?

[英]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.

相关问题 是否允许类在程序中的不同翻译单元之间具有不同的定义? - Are classes allowed to have different definitions across different translation units in a program? const 数据成员可以在翻译单元之间具有不同的值吗? - Can const data members have different values between translation units? 不同翻译单元中的多个定义 - Multiple definitions in different translation units 静态整数,编译单元和三元运算符 - static ints, compilation units and the ternary operator 如果我不使用odr,可以在翻译单元中对它进行多个定义吗? - If I don't odr-use a variable, can I have multiple definitions of it across translation units? 在不同的编译单元中使用不同的编译标志编译相同的标头 - Compiling same header with different compilation flag in different compilation units 编译单元之间共享的全局const对象 - Global const object shared between compilation units 如何在编译时从一些不同的类型中选择类型? - How to choose type from some different on compilation time? 两个翻译单元中的一个定义规则和不同的类定义 - One definition rule and different class definitions in two translation units C++ 结构可以在不同的编译时间有不同的对齐方式吗? - Can C++ structs have different alignments at different compilation times?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM