2016-02-16 30 views
0

在下面的代碼中,我得到了兩個構造函數調用Test u = "u";。但是,如果我註釋掉析構函數,那麼我只能獲得一個構造函數調用。這是爲什麼?爲什麼構造函數調用依賴於缺省析構函數的存在?

#include <iostream> 

template<class T> 
auto operator<<(std::ostream& os, const T& t) -> decltype(t.print(os), os) 
{ 
    t.print(os); 
    return os; 
} 

class Test 
{ 
public: 
    template<typename T> 
    Test(T&& t) 
    { 
     std::cout << "Test " << t << '\n'; 
    } 
    ~Test() = default; // if commented out removes one construction 
    void print(std::ostream& os) const 
    { 
     os << "[with T = Test]"; 
    } 
}; 

int main() 
{ 
    Test u = "u"; // two constructors (second, a temporary, with T = Test) 
    Test t("t"); // one constructor 
} 
+1

問題是什麼?你問爲什麼'u'有兩個構造函數調用,而't'有一個? – NathanOliver

+0

是的。爲什麼當默認的析構函數被註釋掉時,它會成爲一個? – QuentinUK

+0

請更清楚地提出問題,我看不到你在問什麼。 – SergeyA

回答

7

的用戶聲明的析構函數,哪怕是違約,意味着沒有移動構造函數獲取生成。

12.8複製和移動類對象[class.copy]

9如果一個類X的定義不明確宣佈此舉的構造函數,一個將被隱式聲明爲默認,當且僅當

[...]

(9.4) - X沒有一個用戶聲明的析構函數。

如果生成移動構造函數,那麼它比移動模板構造函數更適合移動。它不會保存構造函數調用,它只是意味着不同的構造函數被調用,而不會打印任何東西。

+0

我沒有意識到測試u =「u」;也涉及一個移動構造函數。但是我現在已經添加了移動構造函數,並且沒有被調用。 – QuentinUK

+1

@QuentinUK:還有複製elision。試用'-fno-elide-constructors'。 –

+0

@Kerrek SB,我已經添加了Test(const Test & t);聲明,現在它以兩種方式調用另一個構造函數,但是這個fn甚至沒有被調用(該定義可以被刪除) – QuentinUK

相關問題