我如何制作一个类模板,返回它的任何可变类型是否等于第一个类型。我希望能够做到这一点:
is_same<T, A, B, C>::value; // true if T is one of A, B or C
如果T等于这些类型中的任何一个,则其静态value成员将为true,否则为false。我该怎么做?
T
value
true
false
a6b3iqyw1#
用C++17编写:
template <class T, class... Ts> struct is_any : std::disjunction<std::is_same<T, Ts>...> {};
而dual:
template <class T, class... Ts> struct are_same : std::conjunction<std::is_same<T, Ts>...> {};
使用折叠表达式的变体:
template <class T, class... Ts> struct is_any : std::bool_constant<(std::is_same_v<T, Ts> || ...)> {}; template <class T, class... Ts> struct are_same : std::bool_constant<(std::is_same_v<T, Ts> && ...)> {};
C++20概念:
template <typename T, typename... Ts> concept is_any = std::disjunction_v<std::is_same<T, Ts>...>; template <typename T, typename... Ts> concept are_same = std::conjunction_v<std::is_same<T, Ts>...>;
fcy6dtqo2#
使用模板递归:
template<typename T, typename... Rest> struct is_any : std::false_type {}; template<typename T, typename First> struct is_any<T, First> : std::is_same<T, First> {}; template<typename T, typename First, typename... Rest> struct is_any<T, First, Rest...> : std::integral_constant<bool, std::is_same<T, First>::value || is_any<T, Rest...>::value> {}; static_assert(is_any<int, char, double, int>::value, "error 1"); // OK static_assert(is_any<int, char, double, short>::value, "error 2"); // error
vjrehmav3#
在C++17中,你有一个更好的解决方案,使用模板变量和折叠表达式:
template<class T, class... Rest> inline constexpr bool are_all_same = (std::is_same_v<T, Rest> && ...);
它的用法也比其他例子简单:
are_all_same<T, A, B, C>
没有::value,没有括号!
::value
cnwbcb6i4#
就像这样首先,一个小的元编程库,因为它增加了两行代码来通用地完成它:
template<template<typename,typename>class checker, typename... Ts> struct is_any_to_first : std::false_type {}; template<template<typename,typename>class checker, typename T0, typename T1, typename... Ts> struct is_any_to_first<checker, T0, T1, Ts...> : std::integral_constant< bool, checker<T0, T1>::value || is_any_to_first<checker, T0, Ts...>::value> {};
然后是is_any_same_to_first的两行实现:
is_any_same_to_first
template<typename... Ts> using is_any_same_to_first = is_any_to_first< std::is_same, Ts... >;
为了完整起见,原始的is_all也可能被证明是有用的:
is_all
template<template<typename,typename>class checker, typename... Ts> struct is_all : std::true_type {}; template<template<typename,typename>class checker, typename T0, typename T1, typename... Ts> struct is_all<checker, T0, T1, Ts...> : std::integral_constant< bool, checker<T0, T1>::value && is_all<checker, T0, Ts...>::value> {}; template<typename... Ts> using is_all_same = is_all< std::is_same, Ts... >;
is_all_same的Live example。请注意,调用is_any_same_to_first任何不太明确的内容都是自找麻烦。2/3的人试图回答这个问题,包括我,假设is_same<A,B,C>是真的,当且仅当这三个是相同的类型!
is_all_same
is_same<A,B,C>
7jmck4yq5#
使用宽松的C++14 constexpr函数,这类东西更容易编码,编译速度也可能更快,所以你可以写:
template <class T, class ... Candidates> constexpr bool is_all_same() { bool pairs[] = {std::is_same<T,Candidates>::value...}; for(bool p: pairs) if(!p) return false; return true; } template <class T, class ... Candidates> constexpr bool is_any_same() { bool pairs[] = {std::is_same<T,Candidates>::value...}; for(bool p: pairs) if(p) return true; return false; }
这是因为在C++14中constexpr函数可以有for循环。
wlzqhblo6#
最通用的版本:
#include <type_traits>
is_same
is_same_all
template <typename First, typename Second, typename ... Next> struct is_same { template <typename A, typename B> struct is_same_min { enum { value = false }; }; template <typename A> struct is_same_min<A,A> { enum { value = true }; }; template <typename X, typename Y> constexpr static bool check() { return is_same_min<X,Y>::value; }; template <typename X, typename Y, typename Z, typename ... K> constexpr static bool check() { return is_same_min<X,Y>::value and check<Y, Z, K...>(); }; enum { value = check<First, Second, Next...>() }; };
使用is_same<T1,T2,T3...>::value即可
is_same<T1,T2,T3...>::value
6条答案
按热度按时间a6b3iqyw1#
用C++17编写:
而dual:
使用折叠表达式的变体:
C++20概念:
fcy6dtqo2#
使用模板递归:
vjrehmav3#
在C++17中,你有一个更好的解决方案,使用模板变量和折叠表达式:
它的用法也比其他例子简单:
没有
::value
,没有括号!cnwbcb6i4#
就像这样首先,一个小的元编程库,因为它增加了两行代码来通用地完成它:
然后是
is_any_same_to_first
的两行实现:为了完整起见,原始的
is_all
也可能被证明是有用的:is_all_same
的Live example。请注意,调用
is_any_same_to_first
任何不太明确的内容都是自找麻烦。2/3的人试图回答这个问题,包括我,假设is_same<A,B,C>
是真的,当且仅当这三个是相同的类型!7jmck4yq5#
使用宽松的C++14 constexpr函数,这类东西更容易编码,编译速度也可能更快,所以你可以写:
这是因为在C++14中constexpr函数可以有for循环。
wlzqhblo6#
最通用的版本:
#include <type_traits>
)is_same
适用于n类型(不需要is_same_all
)使用
is_same<T1,T2,T3...>::value
即可