2012-11-16 50 views
7

Tôi có một vấn đề với variadic mẫu mẫu:mẫu vấn đề mẫu cú pháp với các mẫu variadic

  template <typename T> class A { }; 
      template< template <typename> class T> class B { }; 
      template <template <typename> class T, typename parm> class C { typedef T<parm> type; }; 
      template <typename... types> class D { }; 
      template <template <typename...> class T, typename ... parms> class E { typedef T<parms...> type; }; 

      // How to pass list in list?? 
      template < template <typename...> class ...T, ???> 
      class F 
      { 
      }; 

Thứ nhất, vượt qua một loại để mẫu, không có vấn đề:

  A<int> a; //ok 

Bây giờ, tôi muốn tạo một cá thể từ B, nhưng không có cách nào để chuyển thông số mẫu của mẫu:

  B<A> b; // ok, but no chance to submit <int> inside A! 

Vì vậy, tôi phải mở rộng pa danh sách rameter:

  C<A, int> c; // ok, this transport int as parm into A 

Bây giờ tôi chơi với các mẫu variadic trong thời trang tiêu chuẩn:

  D<> d1; // ok 
      D<int, float, double> d2; //ok 

Đi qua các thông số vào phần variadic cũng là eo biển về phía trước:

  E<D> e1; //ok 
      E<D, double, float, int> e2; //ok 

NHƯNG: Nếu tôi muốn để có danh sách các danh sách, tôi không tìm thấy cú pháp nào để tôi có thể chuyển các danh sách tham số vào danh sách các loại. Những gì tôi có ý định là một cái gì đó như thế này. nhưng cũng là ví dụ trên cho thấy rằng B<A<int>> b; là một lỗi! Vì vậy, ví dụ sau đây không thể làm việc :-(

  F< D< int, float>, D< int>, D <float, float, float> > f; 

mục tiêu của tôi là để cuộn danh sách các danh sách thông qua mẫu chuyên môn. Bất kỳ gợi ý?

Giải pháp của tôi sau khi tôi đã hiểu được vấn đề. Cảm ơn!

Bây giờ tôi có thể bỏ mẫu mẫu variadic variadic của mình như trong ví dụ sau: Vấn đề đơn giản là, tôi đợi một lớp mẫu và không phải cho một kiểu đơn giản. Đôi khi, giải pháp có thể dễ dàng như vậy :-)

Thats kết quả của tôi làm việc bây giờ:

template <typename ... > class D; 

    template <typename Head, typename... types> 
    class D<Head, types...> 
    { 
     public: 
      static void Do() { cout << "AnyType" << endl; D<types...>::Do(); } 
    }; 

    template<> 
    class D<> 
    { 
     public: 
      static void Do() { cout << "End of D" << endl; } 
    }; 

    template < typename ...T> class H; 

    template < typename Head, typename ...T> 
    class H<Head, T...> 
    { 
     public: 
      static void Do() 
      { 
      cout << "unroll H" << endl; 
      cout << "Subtype " << endl; 
      Head::Do(); 
      H<T...>::Do(); 
      } 
    }; 

    template <> 
    class H<> 
    { 
     public: 
      static void Do() { cout << "End of H" << endl; } 
    }; 


    int main() 
    { 
     H< D<int,int,int>, D<float, double, int> >::Do(); 
     return 0; 
    } 

Trả lời

2

Bạn có thể giải nén một chuyên variadic tại một thời điểm thông qua chuyên môn:

template<typename...> struct S; 
template<> struct S<> { constexpr static int n = 0; }; 
template<template<typename...> class T, typename... Us, typename... Vs> 
struct S<T<Us...>, Vs...> { 
    constexpr static int n = sizeof...(Us) + S<Vs...>::n; 
}; 

template<typename...> struct D {}; 

#include <iostream> 
int main() { 
    std::cout << S<D<int, int, int>, D<int, int>, D<int>>::n << '\n'; // prints 6 
} 
+0

Cảm ơn, câu trả lời của bạn mở mắt. Tôi đặt giải pháp cuối cùng cho câu hỏi của mình. Hy vọng điều này sẽ giúp người khác. – Klaus

1

Như thế này:

template < template <typename...> class ...T > 
class F 
{ 
}; 
int main() 
{ 
    F< D, D > f; 
} 

Vì vậy, những gì F được mong đợi là một lớp mẫu variadic, mà sẽ đưa một mẫu variadic lớp như đó là cuộc tranh cãi.

Bạn không thể mở rộng đối số của các đối số của đối số lớp mẫu. Nếu bạn chuyên lớp mẫu mà bạn chuyển làm đối số, thì bạn sẽ nhận được phiên bản chuyên biệt.

này:

F< D< int, float>, D< int>, D <float, float, float> > f; 

không làm việc, kể từ F hy vọng variadic mẫu lớp, tham gia các lớp mẫu variadic như các loại, và D< int, float> không phải là một mẫu nữa (nó là một lớp bê tông).

+0

@Klaus Bạn đã viết: 'không có cơ hội để gửi bên trong A!'. Bạn có thể làm trong A này 'typedef A type' và sử dụng nó trong B như 'typename A :: type', nhưng bạn không thể làm điều đó trong một mẫu variadic (điều này không thể được thực hiện:' typedef typename ... types') –

+0

Dường như tôi đang trên con đường hoàn toàn sai và mẫu mẫu variadic không phải là giải pháp. Có cách nào khác để có được chức năng cần thiết không? Nó rất dễ dàng để có được một danh sách có thể được mở rộng thông qua chuyên môn. Tôi vẫn còn hy vọng rằng đó cũng là một cách để những điều như vậy cũng với một danh sách các danh sách. Bất kỳ gợi ý là wellcome! Bạn có thể cho tôi một ví dụ làm việc về ý bạn trong bình luận cuối cùng của bạn không? – Klaus

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