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

Template Argument Deduction guide for unique_ptr argument type?

是否可以编写推导指南,以便在不使用模板参数的情况下声明 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
}

Is it possible to write a deduction guide so that an instance of Simple can be declared without template arguments? I've tried but cannot get the correct form to extract the std::unique_ptr element type.

问题是另一个。

隐式生成的推导指南完全能够为 Simple.

提取正确的类型模板参数

正如 Rakete1111 所指出的,这是一种 "most vexing parse" 问题。

写作

Simple( upSimple );

您的意图是获得类型为 Simple 的未命名临时对象的初始化(Simple<MyThing>,感谢新的 C++17 隐式生成的推导指南)用对象 upSimple.

不幸的是,编译器(visual-c++,但与 g++ 和 clang++ 相同)将其解释为新变量的声明(请注意,声明 C++ 变量的括号是多余的,但完全合法;使用 int (i); 你声明一个变量 i 类型 int) 名称 upSimple 类型 Simple.

这会出错,因为

(1) upSimple 是在前一行中定义的,所以我们重新声明了 upSimple

(2) 在没有构造函数参数的情况下,隐式生成的推导指南无法为 Simple.

推导模板参数 T

为了避免这种歧义,并获得一个Simple<MyThing>对象的初始化,你可以将值保存在一个变量中

auto s = Simple(upSimple);

或者也有

Simple s(upSimple);

因此编译器无法再将此行解释为变量 upSimple 的声明。

如果你真的想要一个未命名的临时对象,你可以使用统一初始化(你可以用大括号代替圆括号)

//.....V..........V
Simple { upSimple };

不能解释为变量声明。

而且,是的:强制使用新的 C++17 标准(通过 /std:c++17-std=c++17 或特定编译器所需的任何一个)也是有用的。