以下代码
template <typename MemberType>
struct Holder {
static MemberType member;
};
template <typename MemberType>
auto Holder<MemberType>::member;
如果我们尝试访问Holder :: member:,在MSVS 2013中产生错误C2371
错误C2371:&#39;会员&#39; :重新定义;不同的基本类型
但是,如果在初始化时我们使用模板参数名称而不是&#39; auto&#39;关键字
template <typename MemberType>
MemberType Holder<MemberType>::member;
按预期编译。那么,在这种情况下编译器无法推断静态成员类型的原因是什么?
答案 0 :(得分:1)
使用占位符auto
/ decltype(auto)
的变量声明必须具有要推断的变量类型的初始值设定项:
使用
auto
或decltype(auto)
声明的变量类型是从其初始化程序推导出来的。在块(6.3),命名空间范围(3.3.6)和 for-init-statement (6.5.3)中声明变量时,允许使用此方法。auto
或decltype(auto)
将在 decl-specifier-seq 和 decl-specifier中显示为 decl-specifiers 之一seq 后面应跟着一个或多个 init-declarators ,每个 init-declarators 都应有一个非空初始值设定项。
您的示例没有定义初始值设定项,因此您的代码格式不正确。
静态成员的定义可能有占位符,但示例中的问题与您使用模板的事实有关,静态成员的声明依赖于模板参数。例如,这个定义不会编译:
template <typename MemberType>
auto Holder<MemberType>::member = 42; // error: redefinition of 'member' with
// a different type: 'int' vs 'MemberType'
Holder<MemberType>
会导致隐式实例化,编译器将查看Holder<MemberType>::member
的声明。编译器在此实例化时不知道从初始化器(int
)推导出的类型是否与MemberType
匹配,这就是为什么你得到奇怪的错误&#34; {{1 }} vs int
&#34;。
如果您创建数据成员的显式特化,则上述代码有效,因为在实例化时已知MemberType
:
MemberType