获取模板化函数的地址是否应该触发其编译?
我得到了这个问题的官方回答,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
inx
, which is of non-class typeint
但如果我只是定义 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.
相关文章