2015-06-20 15 views
8
#include <type_traits> 

struct A{}; 
struct B{}; 

template <typename T> 
struct Foo 
{ 
    typename std::enable_if<std::is_same<T, A>::value>::type 
    bar() 
    {} 

    typename std::enable_if<std::is_same<T, B>::value>::type 
    bar() 
    {} 
}; 

Thông báo lỗi:Tại sao SFINAE (enable_if) không hoạt động đối với các chức năng thành viên của một mẫu lớp?

14:5: error: 'typename std::enable_if<std::is_same<T, B>::value>::type Foo<T>::bar()' cannot be overloaded 10:5: 
error: with 'typename std::enable_if<std::is_same<T, A>::value>::type Foo<T>::bar()' 

Nguồn trên cpp.sh. Tôi nghĩ cả hai typename std::enable_if<std::is_same<T,?>::value>::type không thể hợp lệ cùng một lúc.

Sửa

Đối với hậu thế ở đây là chỉnh sửa của tôi dựa trên câu trả lời @ KerrekSB của - SFINAE chỉ hoạt động cho suy luận mẫu luận

#include <type_traits> 

struct A{}; 
struct B{}; 

template<typename T> 
struct Foo 
{ 
    template<typename U = T> 
    typename std::enable_if<std::is_same<U,A>::value>::type 
    bar() 
    { 
    } 

    template<typename U = T> 
    typename std::enable_if<std::is_same<U,B>::value>::type 
    bar() 
    { 
    } 
}; 

int main() 
{ 
}; 

Trả lời

12

SFINAE chỉ hoạt động cho suy luận luận mẫu, tức là cho các mẫu chức năng. Trong trường hợp của bạn, cả hai mẫu đều được khởi tạo vô điều kiện và việc khởi tạo không thành công.

Các biến thể sau đây hoạt động:

struct Foo 
{ 
    template <typename T> 
    typename std::enable_if<std::is_same<T, A>::value>::type bar(T) {} 

    // ... (further similar overloads) ... 
}; 

Bây giờ Foo()(x) nguyên nhân nhiều nhất là một trong những định nghĩa chồng được khởi tạo, vì thay tham số thất bại trong tất cả những người khác.

Nếu bạn muốn gắn bó với cấu trúc ban đầu của bạn, sử dụng rõ ràng lớp mẫu chuyên môn:

template <typename> struct Foo; 

template <> struct Foo<A> { void bar() {} }; 
template <> struct Foo<B> { void bar() {} }; 
+1

* SFINAE chỉ hoạt động cho các đối số mẫu suy luận * ... Đó là chìa khóa !!!!! Cảm ơn bó @Kerrek. BTW, bài viết gốc của tôi là MWE. – Olumide

+2

@Olumide: Có, chỉ những lỗi thay thế do khấu trừ không phải là lỗi. Thay thế yêu cầu rõ ràng không thành công như một lỗi cứng. (An MFE là đủ cho trường hợp này!) –

+0

Có cách nào có một constructor quá tải như thế này? – Brent

Các vấn đề liên quan