2012-11-26 27 views
4

我在理解何時以及是否調用移動構造函數或移動賦值運算符時遇到了一些問題,特別是在具有常數數據成員的類的上下文中。 考慮類使用常數數據成員或引用成員移動類的ctor

template<typename T> class A { 
    const*T const P ; // constant data member 
    explicit A(const*T p) : P(p) { std::cerr<<" ctor: P="<<P<<'\n'; } 
    void test() const { std::cerr" test: P="<<P<<'\n'; } 
    // move and copy constructors and assignment operators here 
}; 

和測試程序

class B { 
    int X[100]; 
    A<B> get_a() const { return A<B>(this); } 
}; 

int main() { 
    B b; 
    A<B> a = b.get_a(); // which operator/ctor is used for '=' here? 
    a.test(); 
} 

然後編譯的結果是根據所提供的移動構造函數的定義不同,在A<>類移動賦值運算符,同時也對編譯器。

沒有(如上)A<>類的任何進一步聲明,既克++(4.7.0)和ICPC(13.0.1)編譯細(帶有選項-std=c++11)併產生期望的輸出

ctor: P=0x7fffffffd480 
test: P=0x7fffffffd480 

如果我聲明

A&A::operator=(A&&) = delete; 
A&A::operator=(const A&) = delete; 

(這似乎鑑於其必須初始化劑列表初始化常數數據成員的顯),但不提供任何進一步的ctor,使用g ++編譯失敗,但沒關係icichc ic。如果除此之外,我定義(或兩者)

A::A(A&&) = default; 
A::A(const A&) = default; 

這兩個編譯器都很高興。然而,g ++對組合不滿意

A::A(A&&) = delete; 
A::A(const A&) = default; 

雖然icpc很高興。

如果我玩同一遊戲中,不同之處在於A::A(A&&) = default;

A::A(A&&a) : P(a.P) { std::cerr<<" move ctor: P="<<P<<'\n'; } // never called? 

(和等效對於A::A(const A&))代替,結果是完全一致的,特別是沒有輸出由這些顯式移動和複製ctors生成。

那麼哪個運營商用於=main()? (以及爲何沒有輸出在最後的測試產生的?)

爲什麼是這樣的操作在這裏允許在所有的,因爲A<>具有恆定的數據成員(結果是相同的,如果我取代成員const*T const P;const T&R)?

最後,如果有g ++和icpc的不同行爲,如果有的話是正確的?

回答

2
A<B> a = b.get_a(); 

不是一個賦值,而是一個來自右值的a的初始化。這句法應該在C++ 0x中失敗,如果

  1. 移動的構造被刪除,
  2. 移動構造函數聲明explicit
  3. 拷貝構造函數被刪除,並且沒有轉移構造函數的定義,
  4. 未定義移動構造函數,同時定義或刪除移動分配。

聲明或刪除複製賦值運算符應該沒有任何影響。

更正:與複製構造函數不同(即使提供了用戶定義的複製賦值運算符也是合成的),如果定義了用戶定義的移動賦值,編譯器不會合成移動構造函數。因此,上面的名單應該修改4(我現在已經完成)。

因此,我認爲,

  • [1]中的問題,兩種編譯器正確,行爲
  • [2]/1,GCC正確行爲(移動分配防止移動構造函數的代),icpc是錯誤的,
  • in [2]/2,兩個編譯器都正確,
  • in [2]/3,gcc是正確的,因爲移動構造函數被顯式刪除; icpc是錯誤的,
  • [3]對我來說是一個謎。你確定你是對的嗎?
+0

所以這意味着g ++和icpc在這裏犯了幾個錯誤?特別是,如果所有相關操作都應寫入stderr,我仍然對缺少任何輸出產生困惑。 – Walter

+0

我很確定關於[3]。你可以自己嘗試,代碼是微不足道的。順便說一句,爲什麼析構的存在改變了遊戲? – Walter

+0

因爲,根據Torsten Will的書,析構函數的存在會阻止自動生成移動構造函數。但是,因爲它並不妨礙複製構造函數的生成,所以我不確定實際上是什麼意思。 – JohnB