想像:
S f(S a) {
return a;
}
Run Code Online (Sandbox Code Playgroud)
为什么不允许别名a和返回值槽?
S s = f(t);
S s = t; // can't generally transform it to this :(
Run Code Online (Sandbox Code Playgroud)
如果复制构造函数S具有副作用,则规范不允许此转换.相反,它需要至少两个副本(一个来自t于a,一个来自a于返回值,另一个是返回值s,且只有最后一个可以省略.请注意,我写了= t上述表示的副本的事实的t到f的a,这仍然是在移动的副作用存在强制性的唯一拷贝/拷贝构造函数).
这是为什么?
我正在考虑开发一些命名参数代码,但它让我想到了一些如下代码:
#include <utility>
int main()
{
using std::make_pair;
auto x = make_pair(1, make_pair(2, make_pair(3, make_pair(4,5))));
}
Run Code Online (Sandbox Code Playgroud)
现在,一个天真的实现将首先执行"make_pair(4,5)",然后将结果复制到"make_pair(3,...)"的第二个元素中,然后将其复制到"make_pair"的第二个元素中(2,......)"等
不幸的是,这会导致O(n ^ 2)性能,并且会产生大量不必要的副本.我无法看到(命名)返回值优化如何帮助.
理想情况下,make_pair(4,5) 意识到它将在最后一个位置x,并在那个地方构建自己.
更进一步:
#include <utility>
int main()
{
using std::make_pair;
auto&& x1 = make_pair(3, make_pair(4,5));
auto x2 = make_pair(1, make_pair(2, std::move(x1)));
}
Run Code Online (Sandbox Code Playgroud)
我也想避免像这样的代码中的副本.
这种优化是否如此明显以至于我应该假设编译器执行它或者是否有另一种方法我应该对其进行编码以避免副本?
使用以下代码时,不显示"hello2",因为在第3行上创建的临时字符串在执行第4行之前死亡.在第1行使用#define避免了这个问题,但有没有办法在不使用#define的情况下避免这个问题?(C++ 11代码没问题)
#include <iostream>
#include <string>
class C
{
public:
C(const std::string& p_s) : s(p_s) {}
const std::string& s;
};
int main()
{
#define x1 C(std::string("hello1")) // Line 1
std::cout << x1.s << std::endl; // Line 2
const C& x2 = C(std::string("hello2")); // Line 3
std::cout << x2.s << std::endl; // Line 4
}
Run Code Online (Sandbox Code Playgroud)
澄清:
请注意,我相信Boost uBLAS存储引用,这就是为什么我不想存储副本.如果您建议我按值存储,请解释为什么Boost uBLAS出错并且按值存储不会影响性能.