如何根据模板化类中的T初始化类型的静态const成员?

Hel*_*bye 3 c++ templates

鉴于以下课程

template <class T>
class A {
    static const B<T> member;
};
Run Code Online (Sandbox Code Playgroud)

如何单独member为每个类实例化A<T>

mig*_*tin 6

简单.和其他任何静态非整数类型一样.

template <class T>
class A {
    static const B<T> member;
};


template <class T>
const B<T> A<T>::member/*(optional-args)*/;
Run Code Online (Sandbox Code Playgroud)

要为不同类型的成员分配不同的成员T,必须使用模板专门化.

要启动模板特化,您必须使用以下语法:

template<>
// ... explicit definition
Run Code Online (Sandbox Code Playgroud)

显式定义的语法基本上与以下语法相同:

template <class T>
const B<T> A<T>::member/*(optional-args)*/;
Run Code Online (Sandbox Code Playgroud)

除了,template <class T>您使用,而不是在template<>哪里T,您放置实际类型.

例如:

template<>
const B<type> A<type>::member(args);
Run Code Online (Sandbox Code Playgroud)

注意:如果您希望在此方案中调用具有模板特化的默认构造函数,请参阅下面的编辑.

您可以替换type任何您想要的类型.有了这个,您可以为每种可能的类型提供不同的参数.虽然如果你太专注,你应该考虑你的设计是否真的适合使用模板.

在这里它是在行动(在线),随意克隆和玩它.

我想我会提到声明必须是模板类所在的位置.换句话说,如果A在标头中声明,则还必须member在头文件中声明分配.您也可以使用内联文件(.inl)和#include声明模板类的头文件中的.inl文件.

编辑:

似乎在C++ 98中,如果引用成员变量,则调用默认构造函数的以下语法不会在GCC或clang下编译:

 template <>
 const B<type> A<type>::member/*()*/;
Run Code Online (Sandbox Code Playgroud)

类型是任何类型.

但是,以下情况:

 template <class T>
 const B<T> A<T>::member/*()*/;
Run Code Online (Sandbox Code Playgroud)

我不确定这是一个错误,还是只是错误的语法.我建议改为做以下事项:

 template <>
 const B<type> A<type>::member = B<type>();
Run Code Online (Sandbox Code Playgroud)

或者如果您使用的是C++ 11,则可以使用大括号来调用默认构造函数,如下所示:

 template <>
 const B<type> A<type>::member{};
Run Code Online (Sandbox Code Playgroud)

如果使用常规括号,编译器将会在A<type>类中使用静态函数,如果不使用括号,则会出现undefined reference to 'A<type>::member'链接器错误.您可以在这里看到.

以下是Aaron和我发现此错误的讨论.