当前位置: 首页 > 知识库问答 >
问题:

模板函数中默认参数的实例化点

柳奇希
2023-03-14

函数模板、成员函数模板、或类模板的成员函数或静态数据成员的专门化可以在翻译单元内具有多个实例化点,并且除了上述实例化点之外,对于在翻译单元内具有实例化点的任何这样的专门化,翻译单元的末尾也被认为是实例化点。类模板的专门化在翻译单元中最多有一个实例化点。任何模板的专门化都可能在多个翻译单元中具有实例化点。如果两个不同的实例化点根据一个定义规则赋予一个模板专门化不同的含义,则程序是格式不良的,不需要诊断。

现在考虑这个最小的可复制示例:

#include <iostream>
#include <array>
struct A {};
std::array<char, 2> show(float, A)
{
    std::cout << "2\n";
    return {};
}
template<typename T>
struct Fun {
    decltype(show(0, T{})) b;
};
template <typename T>
void func(T, int c = sizeof(Fun<T>{}.b))
{
    show(0, T{});
    std::cout << c << '\n';
}
int main()
{
    func(A{});
}
char show(int, A)
{
    std::cout << "1\n";
    return {};
}

GCC和Clang都输出12(godbolt)。

共有1个答案

贺玉石
2023-03-14

正如问题[temp.point]/8所引用的:

如果两个不同的实例化点根据一个定义规则赋予一个模板专门化不同的含义,则程序是格式不良的,不需要诊断。

根据单定义规则,如果定义中使用的名称的函数调用重载解析将产生定义外定义的不同实体,则两个定义就不相同。([basic.def.odr]/6.2)

 类似资料:
  • 如果允许我执行以下操作: 为什么我主要不被允许做以下事情? 但我必须具体说明以下几点: C11引入了默认的模板参数,现在我完全无法理解它们。

  • 是否允许在友元声明中为模板参数提供默认值? Visual Studio 2015似乎允许这样做。gcc拒绝了。我在cppreference页面上找不到任何内容。

  • 我有一个程序如下。有一个基本模板,以及SFINAE的部分专业化。 在2运行程序时,将打印 中的

  • 下面的代码是合法的C(用g-Wall编译干净): 但是,当我尝试使用nvcc编译此文件时,会出现以下错误: nvcc t.cu t.cu(39):警告:当重新声明未引用的函数模板时,指定默认参数是不标准的 t、 cu(39):警告:重新定义默认参数 t.cu(51):警告:重新声明未引用的函数模板时指定默认参数是不标准的 t、 cu(51):警告:重新定义默认参数 t、 cu(53):错误:模板实

  • 我想在模板类之外定义如下所述的函数。 已经为第二个参数尝试了很多组合,它是一个模板,并且也接受默认参数。 我希望它是在类之外定义的实际得到编译器错误,如果它是简单的类型,我可以很容易地在第二个参数中提到int、浮动等。

  • 在 C++中,定义函数时可以给形参指定一个默认的值,这样调用函数时如果没有给这个形参赋值(没有对应的实参),那么就使用这个默认的值。也就是说,调用函数时可以省略有默认值的参数。如果用户指定了参数的值,那么就使用用户指定的值,否则使用参数的默认值。 所谓默认参数,指的是当函数调用中省略了实参时自动使用的一个值,这个值就是给形参指定的默认值。下面是一个简单的示例: 运行结果: 10, 3.5, # 2