2016-10-23 14 views
8

Giả sử bạn có loại bộ dữ liệu và bạn muốn trích xuất gói thông số mẫu của nó để tạo mẫu khác. Nếu đó là mẫu loại, thì tôi có thể có tiện ích như sau:Mẫu biến mẫu?

template < typename Tuple, template <typename...> typename What > 
struct PutTupleInT; 

template < typename... Types, template <typename...> typename What > 
struct PutTupleInT<std::tuple<Types...>, What> 
{ 
    using Result = What<Types...>; 
}; 

Nhưng nếu mẫu mong muốn là mẫu biến thì sao? Trong khi template <typename...> typename What là "trình giữ chỗ" cho mẫu loại, thì "trình giữ chỗ" cho mẫu biến là gì?

Tôi đã thử những điều sau đây cho clang-4.0.0 (trình biên dịch duy nhất lúc này hỗ trợ các tham số mẫu không kiểu với kiểu tự động), nhưng nó không thành công. Trên thực tế tôi không chắc chắn nếu điều này là một cú pháp chính xác cho C + + 17.

template < typename Tuple, template <typename...> auto What > 
struct PutTupleInV; 

template < typename... Types, template <typename...> auto What > 
struct PutTupleInV<std::tuple<Types...>, What> 
{ 
    static constexpr auto value = What<Types...>; 
}; 
+0

Bạn không thể sử dụng 'decltype (vartempl)' và trích xuất loại biến mẫu, đó là những gì bạn quan tâm thực sự? – skypjack

+0

@skypjack Xin lỗi, tôi thực sự không hiểu ý bạn là gì. – Vahagn

Trả lời

6

Tôi không nghĩ bạn có thể làm điều đó. Trích dẫn N4606:

§14.3.3 [temp.arg.template]/1

Một mẫu đối số cho một mẫu mẫu tham số sẽ là tên của một lớp mẫu hay mẫu bí danh, được biểu thị là id-expression.

Mẫu biến không phù hợp với yêu cầu này.


Bạn có thể lừa dối một chút và sử dụng một loại proxy để chọn mẫu:

template < typename Tuple, class Proxy> 
struct PutTupleInTV; 

template < typename... Types, class Proxy> 
struct PutTupleInTV<std::tuple<Types...>, Proxy> 
{ 
    static constexpr auto value = Proxy::template value<Types...>; 
}; 

và sau đó cho

template<typename...> struct foo{}; 
template<typename... Ts> constexpr foo<Ts...> foo_v{}; 
struct use_foo 
{ 
    template<typename... Ts> 
    static constexpr auto value = foo_v<Ts...>; 
}; 

bạn có thể nói

PutTupleInTV<tup, use_foo>::value 

live demo

+0

Cheat thực sự không giúp nhiều, vì nó đòi hỏi các biến được đặt tên là "value" và được đặt trong một struct. – Vahagn

+0

@Vahagn có, bạn phải tự tạo cấu trúc proxy. Tôi không nhìn thấy một cách xung quanh điều này (không có nghĩa là không có, tôi chỉ không biết bất kỳ) – krzaq

0

PutTupleInTV không trùng tên với PutTupleInV. Bạn không chuyên mẫu PutTupleInV nhưng sử dụng cú pháp chuyên để tạo một cái gì đó mới, được gọi là PutTupleInTV.

+0

Đó là lỗi đánh máy, cảm ơn bạn đã chỉ ra. – Vahagn