繁体   English   中英

一对向量构造函数:初始化列表与显式构造

[英]Pair of vector constructors: initializer list vs explicit construction

我用两种方式调用std::pair<vector<int>, int>构造函数:

  • 传入初始化列表
  • 传入一个显式向量(r值)。

出于某种原因,初始化列表版本会复制(并销毁一个)。
这是我的最小代码示例:

auto dummy() {
    return pair<vector<int>, int>{ {1,2,3,4,5}, 1};
}

auto dummy1() {
    return pair<vector<int>, int>{ vector{1,2,3,4,5}, 1};
}

auto dummy2() {
    return optional<vector<int> > { {1,2,3,4,5} };
}

检查编译器资源管理器后,我发现初始化列表dummy()版本调用operator new两次,并delete一次。 dummy2()既没有显式构造版本dummy1()也没有类似的std::optional构造函数。 我不指望这种行为。 有谁知道为什么? 我也和clang一起检查过。

问题来自std::pair构造函数和模板参数推导/重载解析:

pair( const T1& x, const T2& y ); // (1)

template< class U1, class U2 >
pair( U1&& x, U2&& y );           // (2)

请注意,至少有一个“缺失”构造函数:

pair( T1&& x, T2&& y );           // (3)

当您对第一个参数使用list-initialization时,所选的构造函数不是(2) (使用U1 = std::initializer_list<int> )但是(1) 1 因此,您需要构造一个临时的std::vector<int> ,它作为const reference引用到(1) ,它必须进行复制。

您可以通过以下任一方式凭经验确认:

  • 使用上面提到的第三个构造函数创建自己的pair - 在这种情况下,将选择(3) ,并移动临时vector ;
  • 在构造std::pair显式构造一个std::initializer_list<int>
pair<vector<int>, int>{ std::initializer_list<int>{1,2,3,4,5}, 1 };

另一方面, std::optional作为单个模板化构造函数:

template < class U = value_type >
constexpr optional( U&& value );

...但是U有一个默认值,这使得这个构造函数成为重载决策的有效候选者。


1当您调用pair{ {1,2,3,4,5}, 1 }U1位于(2) [temp.deduct.type]#5.6中的非推导上下文中,因此扣除失败,这就是为什么(1)被选中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM