[英]Why type deduction fails for a class member?
让我们假设我们有这个小代码:
template<typename T>
struct Test {
Test(T t) : m_t(t) {}
T m_t;
};
int main() {
Test t = 1;
}
这段代码很容易用[T=int]
编译,用于Test
class。现在如果我写这样的代码:
template<typename T>
struct Test {
Test(T t) : m_t(t) {}
T m_t;
};
struct S {
Test t = 1;
};
int main() {
S s;
}
此代码无法编译并出现以下错误:
invalid use of template-name 'Test' without an argument list
我需要像Test<int> t = 1;
这样写作为class会员上班。 知道为什么会这样吗?
原因
struct S {
Test t = 1;
};
不起作用是因为你实际上并没有在做Test t = 1;
. in class 初始化器只是一种方便的方式,可以告诉编译器在未提供时用什么值初始化t
。 “实际”生成的是
struct S {
S() : t(1) {} // created by the compiler
Test t;
};
在这里你可以更容易地看到t
在你调用构造函数之前没有用初始化器指定。
您的两个片段之间存在差异 - 第一个Test t = 1
声明、定义和初始化一个新变量,而第二个仅声明一个成员变量并指定如何初始化它。
默认成员初始值设定项仅在其成员初始值设定项列表中没有t
的构造函数的上下文中相关,并且很容易有多个构造函数,每个构造函数都以不同的方式初始化t
。
以下是有效的C++, t
的类型应该推导成什么?
struct S {
Test t = 1;
S(){}
S(int):t(1){}
S(double):t(true){}
};
如果要支持这一点,您会遇到使 class 的类型/大小/布局依赖于可能在不同翻译单元中的构造函数的定义的实现问题。 因此,将无法通过 header 文件定义包含类,例如S
(如果将定义移至 some.cpp)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.