(ODR 使用问题)在不同文件中priority_queue名称相同的结构
(ODR-use question) priority_queue of identically named structs in different files
请考虑以下文件:
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 ./ab
# ... ERROR SUMMARY: 0 errors from 0 contexts ...
valgrind ./ba
# ... ERROR SUMMARY: 2 errors from 2 contexts ...
瓦尔格林德对这两个程序的确切输出可以在此要点中找到。
执行以下任一操作时不会发生错误:
- 将"事件"替换为两个文件之一中的任何其他名称
- 使两个结构的大小相同
- 在
main()
中选择第二组两行而不是第一行
将 priority_queue
替换为vector
,并使用push_back
代替push
我倾向于认为这是编译器(编译器错误?(中的一个问题,其中两个版本的模板即时方法的命名priority_queue
相互冲突。
这是一个已知问题,这是一个新错误,还是我错过了什么?
您违反了一个定义规则,因此您的程序具有未定义的行为。
若要修复它,可以将一个或两个结构放入命名空间中,以使它们唯一。 如果在它们自己的 .cpp 文件之外不需要它们,则可以将它们放入匿名命名空间中。
正如John Zwinck所说,这是违反ODR的行为。 您可以使用-flto
来诊断此类违规行为:
$ g++ -O2 -flto a.cpp b.cpp
a.cpp:3:8: warning: type 'struct Event' violates the C++ One Definition Rule [-Wodr]
struct Event {
^
b.cpp:3:8: note: a different type is defined in another translation unit
struct Event {
^
b.cpp:4:12: note: the first difference of corresponding definitions is field 'b'
int a, b;
^
b.cpp:3:8: note: a type with different number of fields is defined in another translation unit
struct Event {
^
相关文章:
- 为什么这个 std::queue/指向结构的指针列表直到 List.Size() == 0 才释放内存?
- 将参数打包的参数传递到 std::queue 中,以便稍后使用不同的函数调用
- C++ queue.front();为什么不从第一个元素开始呢?
- 我可以擦除 std::queue 中间的节点吗?
- 获取大小时是否必须锁定 std::queue?
- 为什么我会收到"invalid conversion from 'Queue*/Stack*' to 'int'"错误消息?
- 销毁 std::queue 会导致内存错误
- 如何将一个 std::queue 的内容附加到另一个
- 使用元素加载 std::queue<uint8_t*> 的更有效方法?
- 为什么 std::queue 没有实现 insert() 而 std::d eque 实现了?
- 带有 std::vector 和 std::queue 的 Prim's 算法,我的代码有什么问题?
- C++程序在 #include 时无法编译<stack>,#include<queue>
- 是boost :: lockfree :: Queue(在多线程程序中)可锁定
- std :: queue :: pop()在其std :: unique_ptr数据上操作
- 通过 std::queue 中的元素的值获取元素的索引
- 如何索引指向数组 [queue] 的指针数组
- 像std::queue这样的c++标准库容器是否保证是可重入的
- 如何使用"priority"进行多线程处理?
- 在 boost::lockfree:queue 默认构造函数的情况下断言失败
- C++ Floating-Point van Emde Boas (vEB) Priority Queue