2010-04-16 21 views
6

Xin hãy nhìn vào mã này:có nguồn gốc lớp như là đối số mặc định g ++

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; 
} 

Biên dịch tạo ra các thông báo lỗi sau trong g ++:

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

Ý tưởng cơ bản (sử dụng lớp có nguồn gốc như giá trị mặc định đối số kiểu tham chiếu cơ sở) hoạt động trong studio trực quan, nhưng không hoạt động trong g ++. Tôi phải xuất bản mã của mình lên máy chủ của trường đại học nơi họ biên dịch mã với gcc. Tôi có thể làm gì? Có điều gì tôi đang thiếu?

+3

Không giải quyết lỗi, nhưng bạn chỉ có thể viết 'int f (base & arg = derived())'. – kennytm

Trả lời

7

Bạn không thể tạo tham chiếu (có thể biến đổi) thành giá trị r. Cố gắng sử dụng tham chiếu const:

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

Tất nhiên bạn không thể sửa đổi arg với tham chiếu const. Nếu bạn phải sử dụng tham chiếu (có thể thay đổi), hãy sử dụng quá tải.

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

+1 để cung cấp quá tải như là một thay thế –

+0

Cảm ơn tất cả các bạn, điều này đã giải quyết được vấn đề của tôi. Phiên bản const là đủ, trong bối cảnh thực tế, cơ sở là một lớp vị ngữ để so sánh mọi thứ, vì vậy tôi không cần phải sửa đổi nó. – Vincent

+2

Bạn đã bị vấp ngã bởi một phần mở rộng Visual Studio, biên dịch với Cảnh báo Cấp 4 và nó sẽ kích hoạt tính năng này. –

4

Sự cố bạn đang gặp phải là bạn không thể sử dụng đối số mặc định tạm thời cho một hàm tham chiếu không tham chiếu. Thời gian không thể bị ràng buộc với tham chiếu không phải const.

Nếu bạn không thay đổi đối tượng trong nội bộ, sau đó bạn có thể chỉ cần thay đổi chữ ký:

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

Nếu bạn đang thực sự sửa đổi được thông qua vào tranh luận, bạn phải sử dụng một số kỹ thuật khác để cho phép đối số tùy chọn , đơn giản nhất trong số đó sẽ được sử dụng một con trỏ có thể được mặc định là NULL.