用于unique_ptr参数类型的模板参数推导指南?

时间:2018-10-03 22:13:26

标签: c++ templates c++17 template-deduction

是否可以编写一个演绎指南,以便可以在没有模板参数的情况下声明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
}

1 个答案:

答案 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或特定编译器需要的方法)也是有用的。