Hao*_*Shi 13 c++ tuples function c++11
我试图在我的函数中避免输出参数.旧功能是:
void getAllBlockMeanError(
const vector<int> &vec, vector<int> &fact, vector<int> &mean, vector<int> &err)
Run Code Online (Sandbox Code Playgroud)
这里vec
是输入参数,fact
,mean
和err
输出参数.我试图将输出参数分组为一个元组:
tuple< vector<int>, vector<int>, vector<int> >
getAllBlockMeanErrorTuple(const vector<int> &vec)
{
vector<int> fact, mean, err;
//....
return make_tuple(fact, mean, err);
}
Run Code Online (Sandbox Code Playgroud)
现在我可以调用新函数:
tie(fact, mean, err) = getAllBlockMeanErrorTuple(vec);
Run Code Online (Sandbox Code Playgroud)
它对我来说看起来更干净.虽然我有一个问题,如何平等分配tie(fact, mean, err)
工作?它是做深拷贝还是移动?因为fact
,mean
和err
内getAllBlockMeanErrorTuple
就会被破坏,我希望它做的举动,而不是深拷贝.
And*_*dyG 15
你的功能签名是tuple< vector<int>, vector<int>, vector<int> >
,这是一个临时的,元素有资格被移动,所以
std::tie(fact, mean, err) = getAllBlockMeanErrorTuple(vec)
Run Code Online (Sandbox Code Playgroud)
应该将指派fact
,mean
和err
.
这是一个示例程序供您自己查看(演示):
#include <iostream>
#include <vector>
#include <tuple>
struct A
{
A() = default;
~A() = default;
A(const A&)
{
std::cout << "Copy ctor\n";
}
A(A&&)
{
std::cout << "Move ctor\n";
}
A& operator=(const A&)
{
std::cout << "Copy assign\n";
return *this;
}
A& operator=(A&&)
{
std::cout << "Move assign\n";
return *this;
}
};
std::tuple<A, A> DoTheThing()
{
A first;
A second;
return std::make_tuple(first, second);
}
int main()
{
A first;
A second;
std::tie(first, second) = DoTheThing();
}
Run Code Online (Sandbox Code Playgroud)
输出:
复制ctor
复制ctor
移动分配
移动分配
请注意,该函数必须创建用于返回的向量的副本tuple
,这可能不是您想要的.您可能希望std::move
将元素分为std::make_tuple
:
return make_tuple(std::move(fact), std::move(mean), std::move(err));
Run Code Online (Sandbox Code Playgroud)
这是与上面相同的例子,但是使用了std :: move make_tuple
请注意,使用C++ 17的结构化绑定,您可以完全忘记使用std::tie
,并且更多地依赖它auto
(谢谢,@ Yakk):
auto[fact, mean, err] = getAllBlockMeanErrorTuple(vec);
Run Code Online (Sandbox Code Playgroud)
clang(3.8.0)和gcc(6.1.0)的C++ 17标准的早期实现还不支持它,但似乎在clang 4.0.0中有一些支持:演示(谢谢,@ Revolver_Ocelot )
您会注意到带有结构化绑定的输出更改为:
移动ctor
移动ctor
表明他们利用了copy-elision,这节省了额外的移动操作.
Jar*_*d42 12
std::tie(fact, mean, err) = getAllBlockMeanErrorTuple(vec);
Run Code Online (Sandbox Code Playgroud)
会做一个移动任务.
但正如评论中提到的那样
return make_tuple(fact, mean, err);
Run Code Online (Sandbox Code Playgroud)
会做一个副本,你可以解决这个问题:
return make_tuple(std::move(fact), std::move(mean), std::move(err));
Run Code Online (Sandbox Code Playgroud)