【发布时间】:2016-06-07 00:49:37
【问题描述】:
你能告诉我如何显式调用模板构造函数(在初始化列表中)吗? 例如:
struct T {
template<class> T();
};
struct U {
U() : t<void>() {} //does not work
T t;
};
谢谢
【问题讨论】:
你能告诉我如何显式调用模板构造函数(在初始化列表中)吗? 例如:
struct T {
template<class> T();
};
struct U {
U() : t<void>() {} //does not work
T t;
};
谢谢
【问题讨论】:
这是不可能的。该标准还在14.8.1/7
[注意:因为显式模板实参列表跟在函数模板名之后,并且因为转换成员函数模板和构造函数成员函数模板是在不使用函数名的情况下调用的,所以没有办法为这些提供显式模板实参列表功能模板。 ]
解释:这表示:模板参数在函数模板名称后的尖括号中传递,例如std::make_pair<int, bool>。并且构造函数没有自己的名字,但是他们在各种上下文中滥用自己的类名(所以U<int>()的意思是:将<int>传递给类模板U,并通过调用默认构造函数来构造一个对象论据)。因此,不能将模板参数传递给构造函数。
在您的情况下,您尝试在成员初始化程序中传递模板参数。在这种情况下,问题就更大了:它会尝试将t<void> 解析和解释为基类类型,并认为您要调用基类的默认构造函数。这当然会失败。
如果你能忍受它,你可以解决它
struct T {
template<class U> T(identity<U>);
};
struct U {
U() : t(identity<void>()) {}
T t;
};
给定identity,就像它在 boost 中定义的那样
template<typename T> struct identity { typedef T type; };
在 C++20 中,您可以使用 std::type_identity 作为标识类型。
【讨论】:
T(),那么T 是结构T 的名称,而不是构造函数的名称(它没有)。因此,如果您说T<...>(),那么无论传递什么参数,都不会传递给构造函数,而是会尝试传递给根本不是模板的结构。
explicit template argument list、function template name、conversion member function templates、constructor member function templates。我几乎不懂那些抽象的术语(对不起,无法抗拒双关语)。再次阅读您的新评论和段落后,我可能会理解(尽管我仍然不知道术语)。我认为这是说: t<void>() 不起作用,因为模板词缀总是在类型名称或函数名称之后,而t 两者都不是。那正确吗? (但为什么不改变标准以允许它呢?)