7

得到了这个不应触发函数编译的问题的官方答案。事实上,声明但未定义的函数是合法的。decltypedecltype

下一个问题,获取函数的地址是否应该触发函数的编译?举个例子

template <typename T>
void foo(T&& x) { x.func(); }

int main()
{
    auto bar = &foo<int>;
}

我测试过的所有编译器都失败,并出现如下错误:

对非类类型的成员func的请求xint

但是如果我只是定义foo而不声明它,代码编译得很好。有人可以向我提供有关获取函数地址是否需要编译的官方资料吗?

4

1 回答 1

2

3.2/2:

一个表达式可能被求值,除非它是一个未求值的操作数(第 5 条)或其子表达式。... 一个非重载函数,其名称显示为潜在求值表达式或一组候选函数的成员,如果在从潜在求值表达式中引用时通过重载决议选择,则为 odr-used,除非它是一个纯虚函数,它的名字没有明确限定。

然后 3.2/3:

每个程序都应包含该程序中 odr 使用的每个非内联函数或变量的准确定义;无需诊断。定义可以显式出现在程序中,可以在标准或用户定义库中找到,或者(在适当时)隐式定义(参见 12.1、12.4 和 12.8)。内联函数应在使用它的每个翻译单元中定义。

函数名称绝对不是未计算的操作数(例如 to sizeof, decltype),并且它出现在表达式中,因此它可能会被计算。然后第二个需要在每个翻译单元中恰好有一个非内联定义或相同的内联定义。

于 2016-07-15T17:53:12.793 回答