Ori*_*ent 2 c++ optimization move-semantics perfect-forwarding c++11
考虑一个类的两个实现:
struct S1
{
std::vector< T > v;
void push(T && x) { v.push_back(std::move(x)); }
void push(T const & x) { push(T(x)); }
void pop() { v.pop_back(); }
void replace(T && x) { pop(); push(std::move(x)); }
void replace(T const & x) { replace(T(x)); }
};
struct S2
{
std::vector< T > v;
void push(T x) { v.push_back(std::move(x)); }
void pop() { v.pop_back(); }
void replace(T x) { pop(); push(std::move(x)); }
};
Run Code Online (Sandbox Code Playgroud)
S1的push重载表达正是我想要的.S2这push是一种以不那么冗长的方式表达它的方式.
但我担心对象的过度移动构造存在缺陷.
现代编译器可以减少表达std::move(T(std::move(t)))对std::move(t)一些t地方decltype(t)是T&?现代编译器可以优化不必要的移动吗?或者这是否被标准禁止?
不,除了as-if优化之外,这种省略不合法.
现在,如果foo()是一个返回a的表达式T,那么S{}.push(foo())可以忽略从返回值foo()到参数的push移动:只进行一次移动.
但是,如果我们S{}.push(std::move(foo()),明确std::move阻止了省略的可能性.
通常更好的方法是基于动作的操作而不是基于推送的操作.
template<class...Args>
void emplace(Args&&...args) {
v.emplace_back( std::forward<Args>(args)... );
}
Run Code Online (Sandbox Code Playgroud)
这允许您传递参数以构造T对象,并使其直接构建在接收器(向量)中,而不是移动或复制到其中.
可选:
template<class...Args,
decltype(T(std::declval<Args&&>()...))* =0
>
void emplace(Args&&...args) {
v.emplace_back( std::forward<Args>(args)... );
}
Run Code Online (Sandbox Code Playgroud)
如果你想要SFINAE支持.评论说"我们希望在T这里建造一个",如果不是很明显,也是礼貌的.
| 归档时间: |
|
| 查看次数: |
244 次 |
| 最近记录: |