下面的代码 compiles without any error ,虽然它似乎打破了 ODR:
#include <iostream>
template<long Num>
class B;
template<long Num>
struct A {
template<long Num1>
friend void ffoo(A<Num1> a, B<Num>* = nullptr) {
std::cout << "@A ffoo(A<" << Num1 << ">, B<" << Num << ">*)" << std::endl;
}
};
template<long Num>
class B {
public:
friend void ffoo(A<Num> a, B<Num>* = nullptr) {
std::cout << "@B ffoo(A<" << Num << ">, B<" << Num << ">*)" << std::endl;
}
};
int main() {
ffoo(A<1>{}); // @A ffoo(A<1>, B<1>*)
B<1>* ptr = nullptr;
ffoo(A<1>{}, ptr); // @B ffoo(A<1>, B<1>*)
}
ODR Rules 允许 ODR 中断是 IFNDR(病态不需要诊断)的情况,所有这些情况似乎都与具有多个翻译单元的程序有关。first paragraph 非常清楚地说明了单个翻译单元的要求:
上面的代码是否破坏了 ODR?如果是这样,在单个翻译单元内打破 ODR 是否需要编译器诊断?
* 注意:代码示例中的 friend 模板函数似乎确实遵守了 [temp.inst] 的新规则。
最佳答案
B
的 friend 不是函数模板。那个 friend 声明不是模板声明,所以我们有
所以 ffoo
的两个声明并没有声明同一个实体。一个是函数模板,另一个是非模板函数。这两个可能与重载存在于同一声明区域中。
所以这里没有 ODR 违规。
关于c++ - 打破一个 TU 内的 ODR?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/62774917/