何时需要实例化函数模板定义?
When is required instantiation of function template definition?
在我读完这个问题的答案后,我仍然在问问题。答案谈到了 [temp.point] 中定义的实例化点的位置,但如果需要实例化,则不会对其进行评估。
[temp.inst] 指定何时需要函数模板专用化实例化,一般规则为:
实现不应隐式实例化函数模板、变量模板、成员模板、非虚拟成员函数、成员类,[...],除非需要此类实例化。
此外,在标准本节的某些段落中,声明的实例化和定义的实例化是分开考虑的。
让我们考虑以下代码:
static void Yeap0(int);
template <class T>
void Yeap(T a){
Yop(a);
}
template <class T>
auto Yeap2(T a){
Yop(a);
return 0;
}
namespace x{
struct y{};
}
int main() {
Yeap0(0);//ok no definition required here
x::y ax{};
Yeap(ax); //the declaration is sufficient,
Yeap2(ax); //need to deduce auto => definition required
//compilation error
return 0;
}
namespace x{
void Yop(y){}
}
static void Yeap0(int){}
gcc、Clang 和 MSVC 只为Yeap2(ax)
产生一个错误,抱怨Yop
在 Yeap2 的实例化点没有定义。
但是此错误不是为Yeap(ax)
生成的。从基本考虑来看,这似乎是合乎逻辑的,只需要声明,至于 none 模板函数Yeap0
。
但是[temp.inst]/4的讲座让我感到困惑。可以理解,还需要实例化Yeap
。但编译器似乎走了一条更聪明的道路。
编译器行为是扩展吗?
注意:我不会接受"无需诊断"的答案。这将是对智力的侮辱:人们可以相信 3 个编译器特别小心地关闭了像Yeap(ax)
这样的情况的诊断,而不是Yeap2(ax)
?
编译器抱怨实际上来自函数返回auto
的事实。
在auto
的情况下,你真的击中了
除非需要此类实例化。
它必须来自要求 dcl.spec.auto。
若要验证该评估,可以在代码 Yeap2 中替换为:
template <class T>
auto Yeap2(T a){
Yeap(a);
return 0;
}
并且没有编译错误。
相关文章:
- 仅在函数模板中为那些定义了函数的类型执行函数
- 在 C++20 中是否不再允许在 std 中对程序定义类型的函数模板进行专用化?
- 使用定义函数模板别名
- 何时需要实例化函数模板定义?
- 是否可以使用单个定义定义函数的常量和常规版本?(使用模板,自动,decltype等)
- 定义类模板构造函数的两种方法之间的区别
- 使用表达式 SFINAE 的函数模板的类外定义
- 如何为自定义模板对象创建专门的函数模板
- 我应该声明我的函数模板专业化还是定义它们就足够了
- 使用用户定义的转换运算符推导函数模板参数
- 如何定义函数模板中使用的函数?
- 为什么用户定义的转换函数模板不能有推导的返回类型?
- C++,当函子不是一个选项时,我如何编写带有自定义函数调用的模板化 RAII 包装器?
- 关于函数模板中定义的 lambda 闭包类型可以说些什么?
- 错误:重新定义函数模板(或 C2995)
- 调用标头中定义的模板函数时C++链接器错误
- 模板中的自定义函数C++
- 如何严格定义函数模板显式实例化规则
- 定义函数模板
- 错误C2995:已定义函数模板