gpt4 book ai didi

c++ - 具有默认模板参数的模板结构未实例化

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:22:46 24 4
gpt4 key购买 nike

假设我有这段代码

template<typename T2, typename T = int>
struct X
{
static double f;
};

template<typename T>
double X<T>::f = 14.0;

如果我尝试编译 clang 会出现以下错误

nested name specifier 'X::' for declaration does not refer into a class, class template or class template partial specialization

对于海湾合作委员会:

error: template definition of non-template 'double X::f'

问题是:

为什么编译器要我们像这样专门化结构 X:

template<typename T2>
struct X<T2,int>
{
static double f;
};

第一个声明将 int 作为默认参数,为什么编译器不选择这个声明?

我在 standard 中搜索 anchor [temp.spec] 但它没有帮助。

我在回答这个问题后问这个问题one在 SO 上。

感谢您的帮助!

最佳答案

“为什么编译器要我们像那样专门化结构 X”——这不是错误消息所说的。您不需要这样做,而且您真的不应该这样做,除非您想要的是部分特化和仅为该部分特化定义的静态成员。

问题是 template<typename T2, typename T = int> struct X是具有两个 模板参数的类模板。第二个具有默认模板参数的事实并没有改变仍然有两个参数的事实。

因此,您需要将您的类模板成员定义为属于具有两个参数的类模板,如下所示:

template<typename T2, typename T>
double X<T2, T>::f = 14.0;

标准(N4527,当前草案)中的相关段落:

[14.5.1p3]

When a member function, a member class, a member enumeration, a static data member or a member template of a class template is defined outside of the class template definition, the member definition is defined as a template definition in which the template-parameters are those of the class template. The names of the template parameters used in the definition of the member may be different from the template parameter names used in the class template definition. The template argument list following the class template name in the member definition shall name the parameters in the same order as the one used in the template parameter list of the member. Each template parameter pack shall be expanded with an ellipsis in the template argument list.

[14.1p9]

[...] A default template-argument shall not be specified in the template-parameter-lists of the definition of a member of a class template that appears outside of the member’s class. [...]


如上文所述,模板参数的实际名称(T2T)无关紧要,它们可以与类模板定义中的名称不同,但需要保持一致在成员的定义范围内。也就是说,你可以这样做

template<typename T, typename U>
double X<T, U>::f = 14.0;

它仍然会定义正确的 X 的成员类模板。但是,使用相同的名称可以使阅读代码时更容易理解。


通过在定义 f 之前定义偏特化在您的原始示例中,template<typename T> double X<T>::f = 14.0;成为成员 f 的有效定义部分特化的 template<typename T2> struct X<T2,int> ,并且只有那个模板(部分特化本身就是模板)。成员(member)f主模板 template<typename, typename> struct X仍未定义。

相关的写法在[14.5.5.3p1]中:

The template parameter list of a member of a class template partial specialization shall match the template parameter list of the class template partial specialization. The template argument list of a member of a class template partial specialization shall match the template argument list of the class template partial specialization. A class template specialization is a distinct template. The members of the class template partial specialization are unrelated to the members of the primary template. [...]

关于c++ - 具有默认模板参数的模板结构未实例化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31624209/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com