2010-08-16 26 views
5

Trong khi cố gắng trả lời this question Tôi muốn đề xuất sử dụng enable_if + disable_if để cho phép quá tải phương pháp dựa trên thực tế là loại đó (hoặc không) đa hình.enable_if + disable_if kết hợp kích hoạt một cuộc gọi mơ hồ

Vì vậy, tôi đã tạo ra một tập tin thử nghiệm nhỏ:

template <class T> 
void* address_of(T* p, 
       boost::enable_if< boost::is_polymorphic<T> >* dummy = 0) 
{ return dynamic_cast<void*>(p); } 

template <class T> 
void* address_of(T* p, 
       boost::disable_if< boost::is_polymorphic<T> >* dummy = 0) 
{ return static_cast<void*>(p); } 

struct N { int x; }; 


int main(int argc, char* argv[]) 
{ 
    N n; 
    std::cout << address_of(&n) << std::endl; 
    return 0; 
} 

mà có vẻ khá hiền lành.

Tuy nhiên gcc (3,4 ...) sặc về điều này:

test.cpp: In function int main(int, char**) :
test.cpp:29: error: call of overloaded address_of(N*) is ambiguous
test.cpp:17: note: candidates are: void* address_of(T*, boost::enable_if<boost::is_polymorphic<T>, void>*) [with T = N]
test.cpp:20: note: void* address_of(T*, boost::disable_if<boost::is_polymorphic<T>, void>*) [with T = N]

Nó có vẻ khá rõ ràng đối với tâm trí con người của tôi mà quá tải nên được sử dụng ở đây. Tôi có nghĩa là nó có vẻ rõ ràng rằng tôi đã xác định một thay thế và chỉ có một chức năng có thể được sử dụng tại một thời điểm ... và tôi đã có thể nghĩ rằng SFINAE sẽ chăm sóc làm mất hiệu lực quá tải không cần thiết.

Tôi đã vá nó bằng cách sử dụng ... (dấu ba chấm) thay vì disable_if và yêu cầu đối số thứ hai giả ... nhưng tôi vẫn quan tâm đến lý do trình biên dịch bị ngắt.

Trả lời

11

Trình biên dịch nghẹn ngào vì bạn quên trailing ::type trên enable_ifdisable_if. Các mẫu luôn được xác định; chỉ là thành viên type hiện diện nếu và chỉ khi biểu thức là true (đối với enable_if) hoặc false (đối với disable_if).

template <class T> 
void* address_of(T* p, 
       typename boost::enable_if< boost::is_polymorphic<T> >::type* dummy = 0) 
{ return dynamic_cast<void*>(p); } 

template <class T> 
void* address_of(T* p, 
       typename boost::disable_if< boost::is_polymorphic<T> >::type* dummy = 0) 
{ return static_cast<void*>(p); } 

Nếu không có các dấu ::type, mẫu chức năng của bạn chỉ cần tạo quá tải mà mất con trỏ với các trường hợp enable_if hoặc disable_if như tham số thứ hai. Với dấu sau ::type, các mẫu tạo ra quá tải với tham số thứ hai thuộc loại void* hoặc quá tải được loại bỏ (tức là hành vi mong muốn).

+0

Đã chết! Tôi biết nó sẽ hoạt động ... –

0

Sử dụng "kiểu trả về" phiên bản của enable_if làm việc trong 3.4.4: gcc version 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)

#include <boost/utility/enable_if.hpp> 
#include <boost/type_traits/is_polymorphic.hpp> 
#include <iostream> 

template <class T> 
typename boost::enable_if< boost::is_polymorphic<T>, void* >::type 
address_of(T* p) 
{ return dynamic_cast<void*>(p); } 

template <class T> 
typename boost::disable_if< boost::is_polymorphic<T>, void* >::type 
address_of(T* p) 
{ return static_cast<void*>(p); } 

struct N { int x; }; 


int main(int argc, char* argv[]) 
{ 
    N n; 
    std::cout << address_of(&n) << std::endl; 
    return 0; 
} 
Các vấn đề liên quan