我得到了这个问题的官方答案,decltype
不应该触发函数编译。事实上,对已声明但未定义的函数decltype
是合法的。
下一个问题,获取函数的地址是否应该触发函数的编译?举个例子:
template <typename T>
void foo(T&& x) { x.func(); }
int main()
{
auto bar = &foo<int>;
}
我测试过的所有编译器都失败并显示如下错误:
请求会员
func
x
,属于非类类型int
但是如果我只定义foo
而不声明它,代码可以很好地编译。有人可以向我提供官方来源,说明获取函数的地址是否应该需要编译吗?
3.2/2:
表达式可能会被计算,除非它是未计算的 操作数(第 5 条)或其子表达式。...A 非重载 名称显示为潜在计算表达式或 一组候选函数的成员(如果由重载选择) 从潜在计算表达式引用时的分辨率, 是 ODR 使用的,除非它是一个纯虚函数并且它的名字不是 明确限定。
然后 3.2/3:
每个程序应只包含每个非内联的一个定义 该程序中使用的 ODR 函数或变量;无诊断 必填。定义可以显式出现在程序中,它可以 在标准或用户定义的库中找到,或者(当 适当)它是隐式定义的(见 12.1、12.4 和 12.8). 内联函数应在使用它的每个翻译单元中定义。
函数名称绝对不是未计算的操作数(例如 sizeof
、decltype
),并且它出现在表达式中,因此它可能被计算。然后第二个只需要一个非内联定义,或者每个翻译单元中相同的内联定义。