我想编写一个通过移动或复制接收参数的模板函数。
我使用的最有效的方法是:
void setA(A a)
{
m_a = std::move(a);
}
在这里,当我们使用的是
A a;
setA(a); // <<---- one copy ctor & one move ctor
setA(std::move(a)); // <<---- two move ctors
我最近发现这样定义它有两个功能:
void setA(A&& a)
{
m_a = std::move(a);
}
void setA(const A& a)
{
m_a = a; // of course we can so "m_a = std::move(a);" too, since it will do nothing
}
会省很多!
A a;
setA(a); // <<---- one copy ctor
setA(std::move(a)); // <<---- one move ctor
这很棒!对于一个参数...创建具有 10 个参数的函数的最佳方法是什么?!
void setAAndBAndCAndDAndEAndF...()
有人有什么想法吗?
谢谢!
两个 setter 版本setA(A&& a)
and setA(const A& a)
可以使用组合成一个转发参考 https://en.cppreference.com/w/cpp/language/reference#Forwarding_references(又名完美转发):
template<typename A>
void setA(A&& a)
{
m_a = std::forward<A>(a);
}
然后,编译器将根据值类别根据需要合成右值或左值引用版本。
这也解决了多值设置器的问题,因为将根据每个参数的值类别合成正确的设置器。
话虽如此,请记住 setter 只是常规函数;从技术上讲,当可以调用任何 setter 时,该对象就已经构造完毕。的情况下setA
, if A
有一个不平凡的构造函数,然后是一个实例m_a
已经(默认)构建并且setA
实际上必须覆盖它。
这就是为什么在现代 C++ 中,焦点通常不太集中在移动与复制,但是在就地施工与移动/复制。
例如:
struct A {
A(int x) : m_x(x) {}
int m_x;
};
struct B {
template<typename T>
B(T&& a) : m_a(std::forward<T>(a)) {}
A m_a;
};
int main() {
B b{ 1 }; // zero copies/moves
}
除了更传统的“push”/“add”式调用之外,标准库还经常提供“emplace”式调用。例如,vector::emplace https://en.cppreference.com/w/cpp/container/vector/emplace获取构造元素所需的参数,并在向量内构造一个元素,而无需复制或移动任何内容。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)