2010-11-09 54 views
0

讓我用一個簡單的例子證明:拷貝/轉換構造函數的定義(常量/非const)

class A 
{ 
public: 
    A() { cout << "A::A()" << endl; } 
    A(A const& a) : _a(a._a) { cout << "A::(A Copy Const)" << endl; } 
    A(A& a) : _a(a._a) { cout << "A::(A Copy)" << endl; } 

    template <typename _T1> 
    A(_T1& v1) : _a(v1) { cout << "A::(T conversion)" << endl; } 

    ~A() { cout << "A::~A()" << endl; } 

    void say() { cout << "A::say()" << endl; } 

private: 
    int _a; 
}; 

int main(int argc, char* argv[]) 
{ 
    A a1(A(argc)); // Line 1: ERM? 

    a1.say(); 

    return 0; 
} 

幾件事情:

是否有界定一個const和非const任何傷害複製構造函數的版本?原因我做這個的是,這顯然有助於編譯器從模板構造函數區分,即

A const a1(argc); 
A a2(a1); // <-- correctly call the const copy ctor 

A a3(argc); 
A a4(a3); // <-- correctly call the non-const copy ctor 

是否有更好的方法,以確保在上面的例子中,拷貝構造函數總是被調用在模板構造函數?其次,從純粹的編碼角度看,第1行似乎沒問題,目的是創建一個臨時的Aargc,然後觸發複製構造函數,但是我得到以下異常(gcc 4.4.4):

錯誤:請求成員「說」的「A1」,這是無級類,A(A)「

我相信這裏發生了什麼是編譯器認爲a1是函數定義,這是正確的嗎?如果是這樣,那麼編寫該特定行代碼的正確方法是什麼?以下似乎是一個黑客!

A a1(true ? A(argc) : A()); 

p.s.請忽略所有的文體foobar,爲什麼我要這樣做......! :)

回答

2

模板構造函數永遠不是(正式)複製構造函數。

您說得對,可能是函數聲明的聲明被視爲函數聲明。它被稱爲C++的「最令人頭疼的解析」。一種解決方法是使用額外的括號,如T v((U))

這可能是加了一個auto關鍵字也會修復它,我還沒試過。但是,由於auto在C++ 0x中獲得了新的含義,因此即使它在C++ 98中適用於該問題,也可能不是一個好習慣,即使使用它也是一種習慣。

乾杯&心連心。

+0

汽車似乎不能在C++ 98中工作,但圓括號確實有效!謝謝。 – Nim 2010-11-09 18:06:35