初始化列表和 std::forward
Initialization lists and std::forward
我假设的对吗
class D { /* ... */ };
int f (const D & t) { return /* something calculated from t */; }
template<class T>
class C {
private:
int m_i;
T m_t;
// or first m_t, then m_i -- careless order of declarations
public:
template<class T_>
C (T_ && t) : m_t (std::forward<T_> (t)), m_i (f (t)) {
}
};
C<D> c (D ());
可能会导致错误,因为在调用f(t)
时t
的值已被移走?除了 (i) 使用工厂函数或 (ii) 引入对声明m_i
和m_t
顺序的依赖之外,是否有任何方法可以避免此问题?
第一件事是初始值设定项列表的计算顺序由类定义中成员的顺序决定,因此在您的情况下,它将是:
template<class T_>
C (T_ && t)
: m_i (f (t)), m_t (std::forward<T_> (t)) {
}
所以在你的情况下很好。如果对成员重新排序,以便在m_i
之前声明m_t
并在初始化中使用m_t
,也可以:
T m_t;
int m_i;
template<class T_>
C (T_ && t)
: m_t (std::forward<T_> (t)), m_i (f (m_t)) {
}
首先
初始化成员m_i
,到值显然不会移动也不会移动时。当你初始化m_t(std::forward<T>(t))
时,你隐含地承诺你不会使用t
的值(至少,在你给它一个新的值之前)。
通常,执行顺序很重要,成员初始值设定项列表也是如此。也就是说,在成员之间引入依赖关系时,需要注意声明成员的顺序。
相关文章:
- 完美前进使用 std::forward vs RefRefCast
- 你如何理解"std: :forward is just syntactic sugar"?这是真的吗?
- "std::forward"和"std::move"真的不生成代码吗?
- 在C++中使用 std::forward 的多个参数
- 如何使用 std::forward 精确地评估参数包的扩展?
- 普通的右值引用和 std::forward 返回的引用有什么区别?
- 怎么可能写 f( *this, std::forward<Args>(args)... ) 而 f 只用 F f 声明;
- 如何通过通用引用或std::forward将这三个c++模板函数合并为一个
- 自 C++11 年以来对 std::forward 实施的理解
- 当将参数包传递给另一个可变参数模板函数时,我是否必须使用 std::forward
- 为什么要在概念中使用std::forward
- 寻求对std::forward的澄清
- 为什么 std::forward 将左值和右值转换为右值引用?
- std::forward() 的右值引用重载的目的是什么?
- std::forward 如何推断出"_Ty"的类型?
- 没有匹配函数调用 std::forward(const std::string &) 与可变参数
- C++ decltype(auto) or decltype(std::<T>forward(value))?
- std::function operator() 和 std::forward 中发生了什么?
- How to std::forward( *this )
- 在哪些情况下,从 std::forward 分配比从 std::move 分配更可取?为什么