2010-04-16 90 views
6

請看看這個代碼:派生類作爲默認參數克++

template<class T> 
class A 
{ 
class base 
{ 

}; 

class derived : public A<T>::base 
{ 

}; 

public: 

int f(typename A<T>::base& arg = typename A<T>::derived()) 
{ 
    return 0; 
} 
}; 

int main() 
{ 
A<int> a; 
a.f(); 
return 0; 
} 

編譯生成以下錯誤消息克++:

test.cpp: In function 'int main()': 
test.cpp:25: error: default argument for parameter of type 
        'A<int>::base&' has type 'A<int>::derived' 

的基本思想(使用派生類作爲默認值對於base-reference-type參數)在visual studio中工作,但不在g ++中。我必須將我的代碼發佈到大學服務器,然後用gcc編譯它。我能做什麼?有什麼我失蹤?

+3

不解決錯誤,但你可以只寫'int f(base&arg = derived())'。 – kennytm 2010-04-16 13:23:31

回答

7

您無法創建對r值的(可變)引用。嘗試使用const引用:

int f(const typename A<T>::base& arg = typename A<T>::derived()) 
//  ^^^^^ 

當然,您不能使用const引用修改arg。如果您必須使用(可變)引用,請使用重載。

int f(base& arg) { 
    ... 
} 
int f() { 
    derived dummy; 
    return f(dummy); 
} 
+0

+1提供超載作爲替代 – 2010-04-16 13:29:41

+0

謝謝大家,這解決了我的問題。 const版本已經足夠了,在真正的上下文中,base是一個用於比較事物的謂詞類,所以我不需要修改它。 – Vincent 2010-04-16 13:43:06

+2

您已經被Visual Studio擴展程序絆住了,編譯時出現警告級別4,它應該觸發此操作。 – 2010-04-16 15:53:29

4

您面臨的問題是,您不能使用臨時作爲採用非const引用的函數的默認參數。暫時不能綁定到非const引用。

如果不修改內部的對象,那麼你可以改變的簽名:

int f(typename A<T>::base const & arg = typename A<T>::derived()) 

如果你實際上是修改參數傳遞,你必須使用一些其他的技術,支持可選參數其中最簡單的是使用可以默認爲NULL的指針。