下面的代码 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/

10-10 11:16