2015-12-05 13 views
5

Tôi đã nghe ở đâu đó, sử dụng cú pháp C++ 1z mới, thật sự dễ dàng kiểm tra xem loại có được chuyển trong gói tham số mẫu variadic hay không - dường như bạn có thể làm điều này với mã gần một dòng dài. Điều này có đúng không? Các tính năng có liên quan là gì? (Tôi đã thử tìm kiếm thông qua các biểu lần nhưng tôi không thể nhìn thấy làm thế nào để sử dụng chúng trong vấn đề đó ...)Kiểm tra xem loại nào có được chuyển trong gói thông số mẫu variadic

Đây là cách tôi giải quyết vấn đề trong C++ 11 để tham khảo:

#include <type_traits> 


template<typename T, typename ...Ts> 
struct contains; 

template<typename T> 
struct contains<T> { 
    static constexpr bool value = false; 
}; 

template<typename T1, typename T2, typename ...Ts> 
struct contains<T1, T2, Ts...> { 
    static constexpr bool value = std::is_same<T1, T2>::value ? true : contains<T1, Ts...>::value; 
}; 
+1

Trước đó tôi không thấy phần mà bạn nói bạn không thể tìm ra cú pháp biểu thức gấp để thực hiện việc này, tôi cũng đã thêm ví dụ cho điều đó. – Praetorian

Trả lời

13

Bạn đang tìm kiếm std::disjunction. Nó được chỉ định trong N4564[meta.logical].

#include <type_traits> 

template<typename T, typename... Ts> 
constexpr bool contains() 
{ return std::disjunction_v<std::is_same<T, Ts>...>; } 

static_assert( contains<int,  bool, char, int, long>()); 
static_assert( contains<bool,  bool, char, int, long>()); 
static_assert( contains<long,  bool, char, int, long>()); 
static_assert(not contains<unsigned, bool, char, int, long>()); 

Live demo


Hoặc, thích nghi với một struct

template<typename T, typename... Ts> 
struct contains : std::disjunction<std::is_same<T, Ts>...> 
{}; 

Hoặc, sử dụng biểu thức

template<typename T, typename... Ts> 
struct contains : std::bool_constant<(std::is_same<T, Ts>{} || ...)> 
{}; 
gấp

Live demo

+0

Tốt nhất! Tôi thường thấy các giá trị metafunctions được ủy nhiệm bởi thừa kế, nó khá ngắn hơn một chút: 'template <...> struct chứa: std :: disjunction <...> {};' – Quentin

+0

@Quentin Cảm ơn bạn, tốt hơn nhiều. Tôi đã quá ý định sử dụng 'disjunction_v' từ phiên bản hàm :) – Praetorian

+0

Trong biểu thức nếp gấp của bạn -' struct contains: std :: bool_constant <(std :: is_same {} || ...)> '- cú pháp là gì 'std :: is_same {}' có nghĩa là gì? (Ý tôi là, 'std :: is_same ' là một cấu trúc chứa giá trị đúng hoặc sai trong biến thành viên 'value'. Quy tắc cú pháp nào làm' {} 'trích xuất' giá trị' này khỏi cấu trúc?) – qiubit

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