1

我是否正确地假设

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 ());

可能会导致错误,因为调用t时的值已被移走f(t)m_i除了 (i) 使用工厂函数或 (ii) 引入对声明和的顺序的依赖关系之外,还有什么方法可以避免这个问题m_t

4

2 回答 2

3

第一件事是初始化列表的评估顺序由类定义中成员的顺序决定,所以在你的情况下,它将是:

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

所以在你的情况下它很好。如果您重新排序成员以便在之前m_t声明并在初始化中使用它也可以: m_im_t

T m_t;
int m_i;
template<class T_>
C (T_ && t) 
  : m_t (std::forward<T_> (t)), m_i (f (m_t))  {
}
于 2012-11-24T17:57:56.613 回答
2

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

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

于 2012-11-24T17:58:05.800 回答