考虑下面的类模板,它包含同一个朋友(相同的函数类型;见下文)的两个(隐藏)朋友声明,它也定义了朋友(因此朋友是内联的),但定义条件为(互斥)要求条款:
#include <iostream>
struct Base {};
template<int N>
struct S : public Base {
friend int foo(Base&) requires (N == 1) { return 1; }
friend int foo(Base&) requires (N == 2) { return 3; }
};
Run Code Online (Sandbox Code Playgroud)
[dcl.fct] / 8指出尾随需要子句是不函数的类型的一部分。重点矿]:
返回类型、参数类型列表、引用限定符、cv-qualifier-seq 和异常规范,但不是默认参数([dcl.fct.default])或尾部的 requires-clause ([ dcl.decl]),是函数类型的一部分。
这意味着对于两个定义都被实例化的情况,上述两个定义违反了 ODR;如果我们只关注单个翻译单元,[basic.def.odr]/1将被违反:
任何翻译单元不得包含任何变量、函数、类类型、枚举类型、模板、参数的默认参数(对于给定范围内的函数)或默认模板参数的多个定义。
并且在单个 TU 中,这种违规行为应该可以被诊断出来(不需要“格式错误,NDR”)。我正在尝试了解何时实例化上述定义的规则;或者如果这完全是实现定义的(或者甚至在到达实例化阶段之前格式错误)。
Clang 和 GCC (1) …