初始化列表和std :: forward

时间:2012-11-24 17:35:13

标签: c++ constructor move 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 ());

可能会导致错误,因为调用tf(t)的值已被移除?有没有办法避免这个问题,除了(i)使用工厂函数或(ii)引入对m_im_t被声明的顺序的依赖?

2 个答案:

答案 0 :(得分:3)

首先,初始化列表的评估顺序由类定义中成员的顺序决定,因此在您的情况下,它将是:

template<class T_>
C (T_ && t) 
  : m_i (f (t)), m_t (std::forward<T_> (t)) {
}

所以在你的情况下它很好。如果您重新排序成员以便{/ 1}}在 m_t之前声明并且您在初始化中使用m_i,那也没关系:

m_t

答案 1 :(得分:2)

成员m_i首先被初始化,并且当值明显不移动时也不会被移动。初始化m_t(std::forward<T>(t))时,您隐含地承诺不会使用t的值(至少在您给它一个新值之前)。

通常,执行顺序很重要,对于成员初始化列表也是如此。也就是说,当你在它们之间引入依赖关系时,你需要小心你声明你的成员的顺序。