2011-10-07 25 views
5

Tôi có lớp A có tham số mẫu T. Có trường hợp sử dụng lớp T cung cấp hàm func1() và có trường hợp sử dụng T không không cung cấp nó. Một hàm f() trong A nên gọi func1(), iff nó tồn tại. Tôi nghĩ rằng điều này nên có thể với mpl tăng, nhưng tôi không biết làm thế nào. Dưới đây một số mã giả:Tăng MPL: Chỉ gọi hàm (thành viên) nếu nó tồn tại

template<class T> 
class A 
{ 
    void f(T param) 
    { 
     if(T::func1 is an existing function) 
      param.func1(); 
    } 
}; 

Thậm chí tốt hơn sẽ là một người khác hợp cụ thể:

template<class T> 
class A 
{ 
    void f(T param) 
    { 
     if(T::func1 is an existing function) 
      param.func1(); 
     else 
      cout << "func1 doesn't exist" << endl; 
    } 
}; 
+2

Ngay cả khi bạn quản lý để tìm điều kiện thích hợp mà mã sẽ không biên dịch. Cả hai nhánh của if phải biên dịch, và nếu hàm không tồn tại, nhánh thực sẽ không biên dịch. –

+0

Với chuyên môn mẫu, không cần thiết cả hai phần biên dịch. Bằng cách nào đó tôi sẽ phải gọi một hàm mẫu với tham số T và hàm này có một hành vi differend khi T cung cấp hoặc không cung cấp hàm func1(). Tôi chắc chắn tăng mpl cung cấp một cái gì đó cho trường hợp sử dụng này. Tôi chỉ không biết cách sử dụng nó. – Heinzi

+0

Có phải tùy chọn C++ 11 không? –

Trả lời

7

Boost.MPL không đối phó với điều đó vì nó là đúng cho TMP và bạn không thể gọi thành viên trong TMP. Boost.Fusion và Boost.TypeTraits cũng không có gì cả; Tôi nghĩ một trong số họ sẽ nhưng dường như tôi đang rất đáng tin cậy.

Herehere là một số giải pháp về cách viết một đặc điểm để phát hiện thành viên trong C++ 03. Một khi bạn có một đặc điểm như vậy (Tôi sẽ gọi nó has_func1_member), bạn có thể sử dụng nó cho SFINAE:

template<typename T> 
typename boost::enable_if<has_func1_member<T> >::type 
maybe_call(T& t) 
{ t.func1(); } 

template<typename T> 
typename boost::disable_if<has_func1_member<T> >::type 
maybe_call(T&) 
{ 
    // handle missing member case 
} 

// your example code would then do: 
maybe_call(param); 

Lưu ý rằng với C++ 11 nó dễ dàng hơn để viết các đặc điểm ở nơi đầu tiên, mặc dù nó vẫn còn hơi phức tạp.

+0

Bạn có thực sự phải tự viết nó không? Không is_member_function_pointer làm lừa? http://en.cppreference.com/w/cpp/types/is_member_function_pointer hoặc trong Boost: http://www.boost.org/doc/libs/1_51_0/libs/type_traits/doc/html/boost_typetraits/reference/is_member_function_pointer .html – Gurgeh

+0

@Gurgeh Trong C++ 03 nó không giúp ích gì. Trong C++ 11, bạn có thể viết một cái gì đó hoạt động nhưng nó có khả năng sẽ thất bại với các hàm thành viên bị quá tải (sẽ báo cáo sai âm) và có những cách dễ dàng hơn để làm điều đó mà không có nhược điểm đó. –

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