是否可以编写一个演绎指南,以便可以在没有模板参数的情况下声明Simple
的实例?我已经尝试过,但是无法获得提取std::unique_ptr
元素类型的正确形式。
//------------------------------------------------------------------------------
template< class T >
class Simple
{
public:
Simple( std::unique_ptr< T >& u ) :
u_( u )
{}
private:
std::unique_ptr< T >& u_;
};
class MyThing
{};
int main()
{
std::unique_ptr< MyThing > upSimple;
Simple( upSimple ); // error C2955: 'Simple': use of class template requires template argument list
}
答案 0 :(得分:4)
是否可以编写一个演绎指南,以便可以在没有模板参数的情况下声明Simple的实例?我已经尝试过,但是无法获取提取std :: unique_ptr元素类型的正确形式。
问题是另一个。
隐式生成的推导指南完全能够为Simple
提取正确的类型模板参数。
Rakete1111指出,这是一种“最令人头疼的解析”问题。
写作
Simple( upSimple );
您的意图是获取初始化为对象Simple
的类型为Simple<MyThing>
的未命名临时对象的初始化({upSimple
,这要归功于新的C ++ 17隐式生成的推导指南)
不幸的是,编译器(Visual-C ++,但与g ++和clang ++相同)将其解释为新变量的声明(请注意括号中的声明C ++变量是多余的,但完全合法;使用int (i);
时,您声明了一个名称为i
的类型int
的变量upSimple
和类型Simple
。
这是因为
(1)upSimple
在上一行中已定义,因此我们重新声明了upSimple
(2)如果没有构造函数参数,则隐式生成的推论指南无法推断T
的模板参数Simple
。
为避免这种歧义,并获得Simple<MyThing>
对象的初始化,可以使用以下方法将值保存在变量中:
auto s = Simple(upSimple);
或也
Simple s(upSimple);
因此编译器无法再将该行解释为变量upSimple
的声明。
如果您确实想要一个未命名的临时对象,则可以使用统一的初始化(可以使用大括号而不是括号)
//.....V..........V
Simple { upSimple };
不能解释为变量声明。
是的:强加使用新的C ++ 17标准(通过/std:c++17
或-std=c++17
或特定编译器需要的方法)也是有用的。