在 C++ 中创建 setter 函数的最佳方法

2024-02-07

我想编写一个通过移动或复制接收参数的模板函数。 我使用的最有效的方法是:

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(使用前将#替换为@)

在 C++ 中创建 setter 函数的最佳方法 的相关文章

随机推荐