2012-03-15 36 views
5

Các đối số mẫu mặc định có thể được sử dụng để mô phỏng các bí danh cho các biểu thức kiểu phức tạp trong một khai báo mẫu. Ví dụ:Có thể mô phỏng các đối số mẫu mặc định trong các chuyên môn từng phần không?

template <typename X, 
      typename Y = do_something_with<X>::type, 
      typename Z = some_other_thing_using<X, Y>::type 
struct foo { ... X, Y, Z ... }; 

Tuy nhiên, chuyên ngành một phần có thể không có đối số mẫu mặc định ([C++11: 14.5.5/8]), do thủ thuật này không hoạt động. Bạn có thể tự hỏi tại sao một typedef trong cơ thể sẽ không hoạt động, và câu trả lời là các bí danh cần phải nằm trong phạm vi trước nội dung lớp, để thực hiện điều kiện; ví dụ:

template <typename T, typename Enable = void> 
struct bar; 

// Wishful thinking: 
template <typename X, 
      typename Y = do_something_with<X>::type, 
      typename Z = some_other_thing_using<X, Y>::type> 
struct bar <std::vector<X>, 
      typename enable_if< 
       some_condition<X, Y, Z> 
      >::type> 
    { ... }; 

Con đường tôi đã làm việc xung quanh nó được sử dụng một loại phụ trợ:

template <typename X> 
struct bar_enabled { 
    typedef typename do_something_with<X>::type Y; 
    typedef typename some_other_thing_using<X, Y>::type Z; 
    static const bool value = some_condition<X, Y, Z>::value; 
}; 

template <typename X> 
struct bar <std::vector<X>, 
      typename enable_if_c< 
       bar_enabled<X>::value 
      >::type> 
    { ... }; 

Nhưng vì nhiều lý do (trong đó có muốn tránh một loại riêng biệt, mà làm phức tạp những gì tôi làm), tôi hy vọng rằng một giải pháp tốt hơn tồn tại. Bất kỳ ý tưởng?

+1

Mặc định không mô phỏng bất cứ điều gì. Chúng cung cấp mặc định. –

+3

Đối với hồ sơ, "Danh sách tham số mẫu của một chuyên môn sẽ không chứa các giá trị đối số mẫu mặc định" '[C++ 11: 14.5.5/8]' –

+0

@LightnessRacesinOrbit, ý bạn là chỉ ra rằng vấn đề này không có ' t thay đổi trong C++ 11, hoặc cái gì khác? – ajg

Trả lời

3

lẽ bạn có thể dính vào sự phân biệt thành một lớp cơ sở: đối số

template <typename X, typename Y, bool> 
struct BaseImpl    { /* ... */ }; 

template <typename X, typename Y> 
struct BaseImpl<X, Y, true> { /* ... */ }; 

template <typename X, typename Y = typename weird_stuff<X>::type> 
struct Foo : BaseImpl<X, Y, some_condition<X, Y>::value> 
{ 
    // common stuff 
}; 
Các vấn đề liên quan