c++ - (ODR 使用问题)不同文件中同名结构的 priority_queue

标签 c++ g++ one-definition-rule

考虑以下文件:

a.cpp:

#include <queue>

struct Event {  
    int a;
};

static bool operator<(const Event &a, const Event &b) {
    return a.a < b.a;
}

void external_insert(std::priority_queue<Event> &pqu, Event event) {
    pqu.push(event);
}

int main() {
    // fails
    std::priority_queue<Event> pqu;
    external_insert(pqu, Event());

    // works
    // std::priority_queue<Event> pqu;
    // pqu.push(Event());
    return 0;
}

b.cpp:

#include <queue>

struct Event {
    int a, b;
};

static bool operator<(const Event &a, const Event &b) {
    return a.a < b.a;
}

void some_unused_function() {
    std::priority_queue<Event> evqu;
    evqu.push(Event());
}

然后使用以下命令将这两个文件编译成两个可执行文件:

g++ a.cpp b.cpp -o ab
g++ b.cpp a.cpp -o ba

然后在 valgrind 下运行:

valgrind ./ab
# ... ERROR SUMMARY: 0 errors from 0 contexts ...
valgrind ./ba
# ... ERROR SUMMARY: 2 errors from 2 contexts ...

这两个程序的 valgrind 的准确输出可以在 this gist 中找到。 .

执行以下任一操作时不会发生错误:

  • 用两个文件之一中的任何其他名称替换“Event”
  • 使两个结构体大小相同
  • 选择 main() 中的第二组两行而不是第一组
  • priority_queue 的使用替换为 vector,并使用 push_back 代替 push

我倾向于认为这是编译器中的一个问题(编译器错误?),其中两个版本的 priority_queue 的模板实例化方法的命名相互冲突。

这是一个已知问题,这是一个新错误,还是我遗漏了什么?

最佳答案

您违反了单一定义规则,因此您的程序具有未定义的行为。

要修复它,您可以将一个或两个结构放入命名空间中,使它们独一无二。如果在它们自己的 .cpp 文件之外不需要它们,您可以将它们分别放入一个匿名命名空间中。

关于c++ - (ODR 使用问题)不同文件中同名结构的 priority_queue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52627146/

相关文章:

c++ - 静态链接 C++,找不到库

c++ - 是否保证只有一个非内联内联函数的拷贝?

c++ - 运行时符号查找错误

c++ - 异常情况下的智能指针析构函数

c++ - 提交的命令缓冲区出现 CoreValidation-DrawState-InvalidImageLayout 错误

c++ - VS 2017 告诉我我正在尝试转换变量,但我没有

c++ - 如何将 __asm block 转换为基于字符串的 asm(与 G++ 兼容)?

c++ - 多参数模板不能很好地处理友元声明

c++ - 一条定义规则 : Can corresponding entities have different names?

c++ - c++中的一个定义规则