gpt4 book ai didi

c++ - 一对 vector 构造函数 : initializer list vs explicit construction

转载 作者:太空狗 更新时间:2023-10-29 21:10:45 24 4
gpt4 key购买 nike

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

  • 传入初始化列表
  • 传入一个显式 vector (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一次。显式构建版本 dummy1() 都不会发生这种情况也没有类似的 std::optional dummy2() 中的构造函数.我不希望有这种行为。有谁知道为什么?我也用 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)

当你对第一个参数使用列表初始化时,选择的构造函数不是(2) (与 U1 = std::initializer_list<int> )但 (1) 1。因此,您需要构建一个临时的 std::vector<int> , 作为 const 传递-引用(1) , 必须制作拷贝。

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

  • 创建您自己的 pair使用上面提到的第三个构造函数——在本例中,(3)会被选中,临时vector将被移动;
  • 显式构建 std::initializer_list<int>在构建 std::pair 时:
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)被选中。

关于c++ - 一对 vector 构造函数 : initializer list vs explicit construction,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53108740/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com