And*_*owl 63 c++ move-semantics perfect-forwarding c++11 universal-reference
考虑一个X
具有N
成员变量的类,每个类都有一些可复制和可移动的类型,以及N
相应的setter函数.在C++ 98中,定义X
可能如下所示:
class X
{
public:
void set_a(A const& a) { _a = a; }
void set_b(B const& b) { _b = b; }
...
private:
A _a;
B _b;
...
};
Run Code Online (Sandbox Code Playgroud)
X
上面类的setter函数可以绑定到左值和右值参数.根据实际的说法,这可能导致创建临时的,并会最终导致的分配副本; 因此,此设计不支持不可复制的类型.
使用C++ 11,我们可以移动语义,完美转发和通用引用(Scott Meyers的术语),通过以下方式重写它们,可以更有效和广泛地使用setter函数:
class X
{
public:
template<typename T>
void set_a(T&& a) { _a = std::forward<T>(a); }
template<typename T>
void set_b(T&& b) { _b = std::forward<T>(b); }
...
private:
A _a;
B _b;
...
};
Run Code Online (Sandbox Code Playgroud)
通用引用通常可以绑定到const
/非const
,volatile
/非volatile
和任何可转换类型,从而避免创建临时值并直接传递值operator =
.不可复印,可移动的类型现在支持.可能通过static_assert
或通过可以消除不希望的结合std::enable_if
.
所以我的问题是:作为一个设计指南,C++ 11中的所有(比如说,大多数)setter函数是否应该被编写为接受通用引用的函数模板?
除了更麻烦的语法和在这些setter函数中编写代码时使用类似Intellisense的辅助工具的不可能性时,假设原则" 写入setter函数作为函数模板尽可能接受通用引用 "还有任何相关的缺点吗?
Pup*_*ppy 37
你知道A类和B类,所以你知道它们是否可移动,以及最终是否需要这种设计.对于类似的事情std::string
,除非您知道这里存在性能问题,否则更改现有代码会浪费时间.如果你正在处理auto_ptr
,那么是时候把它撕掉并使用了unique_ptr
.
如果您不知道任何更具体的内容,现在通常更喜欢按值获取参数 - 例如
void set_a(A a) { _a = std::move(a); }
Run Code Online (Sandbox Code Playgroud)
这允许使用任何构造器A
而不需要除可移动性之外的任何东西并且提供相对直观的界面.
归档时间: |
|
查看次数: |
4808 次 |
最近记录: |