【问题标题】:Template Argument Deduction guide for unique_ptr argument type?unique_ptr 参数类型的模板参数推导指南?
【发布时间】:2018-10-03 22:13:25
【问题描述】:

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

【问题讨论】:

  • 最头疼的解析又来了!
  • 一旦你修复了令人头疼的解析错误,它仍然无法编译 - MSVC 还不支持 CTAD 吗?
  • 根据@rakete 的观察,编译(在 gcc 下):Simple s ( upSimple );,参见:wandbox.org/permlink/V4bp2fsfk49cYMSd
  • @Barry 最新的 MSVC。 godbolt.org/z/Z1pXRo
  • Simple{upSimple} ?

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


【解决方案1】:

是否可以编写一个推导指南,以便可以在没有模板参数的情况下声明 Simple 的实例?我已经尝试过,但无法获得正确的形式来提取 std::unique_ptr 元素类型。

问题是另一个。

隐式生成的推导指南完全能够为Simple提取正确的类型模板参数。

正如 Rakete1111 所指出的,这是一种“最令人头疼的解析”问题。

写作

Simple( upSimple );

您的意图是获取使用对象 upSimple 初始化的 Simple 类型的未命名临时对象(Simple&lt;MyThing&gt;,感谢新的 C++17 隐式生成的推导指南)的初始化。

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

这会出错,因为

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

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

为避免这种歧义,并获得Simple&lt;MyThing&gt; 对象的初始化,您可以将值保存在变量中

auto s = Simple(upSimple);

或者也有

Simple s(upSimple);

所以编译器不能再将这一行解释为变量upSimple 的声明。

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

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

不能解释为变量声明。

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

【讨论】:

    猜你喜欢
    • 2022-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-30
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 1970-01-01
    相关资源
    最近更新 更多