我目前对C ++ 17保证的RVO及其含义感到困惑。我明白,要让NRVO加入,我需要确保这一点
考虑一个最简单的装饰类Widget,我想分配一对没有副本的小部件,然后返回它
#include<iostream>
#include<utility>
struct Widget {
Widget() { std::cerr << "Default ctor" << std::endl; }
explicit Widget(int i) { std::cerr << "custom ctor" << std::endl; }
Widget(Widget const &) { std::cerr << "copy ctor" << std::endl; }
Widget(Widget &&) { std::cerr << "move ctor" << std::endl; }
Widget &operator=(Widget const &) { std::cerr << "copy assign" << std::endl; }
Widget &operator=(Widget &&) { std::cerr << "move assign" << std::endl; }
int i_;
};
auto foo(){
std::pair<Widget,Widget> w; // default construction
auto &[w1,w2] = w;
// do something with w1 and w2
return w;
}
int main(){
auto f = foo();
}
没有复制,但现在我尝试使用make_pair
auto foo(){
auto w = std::make_pair<Widget,Widget>({},{}); // Awkward syntax and move construction
auto &[w1,w2] = w;
// do something with w1 and w2
return w;
}
如果我想使用make_pair,这真的是唯一可行的选择吗?与第一个函数相比,为什么还有移动构造?
我认为你的问题的前提是错误的。
如果我想使用make_pair,这真的是唯一可行的选择吗?
你为什么要在这里使用std::make_pair
?
auto w = std::make_pair<Widget,Widget>({},{}); // Awkward syntax and move construction
这真的是笨拙的语法。让我解释为什么我这么认为......
来自qazxsw poi on qazxsw poi(强调我的):
创建一个std :: pair对象,从参数类型中推导出目标类型。
cppreference的唯一目的是推断其参数的类型,例如在
std::make_pair
当默认构造一对并且您知道它的类型时,您永远不必重复模板参数
std::make_pair
当你想要非默认构造时(当它的唯一影响是你必须在同一行代码的其他地方拼写类型时,不要使用std::pair<int,int> x;
x = std::pair<int,int>(3,3); // not nice
x = std::make_pair(3,3); // ok
)
std::pair<int,int> a = std::pair<int,int>(); // awkward
底线:
另一种方法是在不需要的时候不使用auto
。