获取模板化函数的地址是否应该触发其编译?

我得到了这个问题的官方回答,decltype 应该不触发函数编译.事实上,decltype 对已声明但未定义的函数是合法的.

I got an official answer to this question that decltype should not trigger function compilation. In fact decltype on a function that is declared but not defined is legal.

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

Next question, should taking the address of a function trigger the compilation of a function? Take this example:

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

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

我测试过的所有编译器都失败并显示如下错误:

All the compilers I've tested fail with an error like:

请求x中的成员func,属于非类类型int

Request for member func in x, which is of non-class type int

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

But if I just define foo and don't declare it, the code compiles fine. Can someone provide me with an official source on whether taking the address of a function should require it's compilation?

推荐答案

3.2/2:

一个表达式可能会被求值,除非它是一个未求值的操作数(第 5 条)或其子表达式.... 一个非重载其名称显示为潜在求值表达式或一组候选函数的成员,如果被重载选中从潜在评估表达式中引用时的分辨率,被 odr 使用,除非它是一个纯虚函数并且它的名字不是明确限定.

An expression is potentially evaluated unless it is an unevaluated operand (Clause 5) or a subexpression thereof. ... A non-overloaded function whose name appears as a potentially-evaluated expression or a member of a set of candidate functions, if selected by overload resolution when referred to from a potentially-evaluated expression, is odr-used, unless it is a pure virtual function and its name is not explicitly qualified.

然后是 3.2/3:

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

Every program shall contain exactly one definition of every non-inline function or variable that is odr-used in that program; no diagnostic required. The definition can appear explicitly in the program, it can be found in the standard or a user-defined library, or (when appropriate) it is implicitly defined (see 12.1, 12.4 and 12.8). An inline function shall be defined in every translation unit in which it is odr-used.

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

The function name is definitely not an unevaluated operand (for example to sizeof, decltype), AND it appears in an expression, so it's potentially evaluated. Then the second one requires exactly one non-inline definition, or identical inline definitions in each translation unit.

相关文章