我想根据std::tuple中的所有元素是否为相同类型来判断true / false。例如
std::tuple<int, int, int> t = { 1, 1, 1}; auto A = all_same(t); std::tuple<int, float, int> t = { 1, 1.0, 1}; auto B = all_same(t);
这里,A为真,B为假无论如何要做到这一点?
jei2mxaa1#
C++17解决方案与折叠表达式:
#include <tuple> template<typename Head, typename...Tail> constexpr bool all_same(const std::tuple<Head,Tail...>&){ return (std::is_same_v<Head,Tail> && ...); } constexpr bool all_same(const std::tuple<>&){ return true; // This is reasonable, right? } int main() { std::tuple<int, int, int> t1{ 1, 1, 1}; static_assert(all_same(t1)); std::tuple<int, float, int> t2{ 1, 1.0f, 1}; static_assert(!all_same(t2)); std::tuple<> t3{}; static_assert(all_same(t3)); }
也许你想使用std::is_same_v的替代品/补充:
std::is_same_v
std::is_convertible
std::swappable
is_convertible
const float&
float
std::decay
xxslljrj2#
当std::tuple<A,B,C,D>和std::tuple<B,C,D,A>是相同类型时,元组std::tuple<A,B,C,D>的类型都相同。
std::tuple<A,B,C,D>
std::tuple<B,C,D,A>
#include <type_traits> #include <tuple> #include <iostream> template <typename First, typename... T> struct all_same_type { constexpr static bool value = std::is_same_v< std::tuple<First,T...>, std::tuple<T...,First>>; }; template <typename... T> struct all_same_type<std::tuple<T...>> : all_same_type<T...> {}; template <typename... T> constexpr bool all_same_type_v = all_same_type<T...>::value; int main() { std::tuple<int, int, int> t = { 1, 1, 1}; std::cout << all_same_type_v< decltype(t)> << "\n"; std::tuple<int, float, int> u = { 1, 1.0, 1}; std::cout << all_same_type_v< decltype(u)> << "\n"; }
Output:
1 0
q9rjltbz3#
下面是使用fold expressions和lambda expression的方法:
#include <tuple> #include <iostream> //for returning result based on both "type and value" template<typename First, typename... Rest> bool allSame(const std::tuple<First, Rest...> &tup ) requires(std::is_same_v<First, Rest> && ...) { return std::apply([](const auto&... nth) { return (true == ... == nth ); }, tup); } //version that always returns false if any type mismatch template<typename First, typename... Rest> bool allSame(const std::tuple<First, Rest...> &tup ) requires (... || !std::is_same_v<First, Rest>) { return false; } int main(){ std::tuple<int, int, int> t = { 1, 1, 1}; std::cout << allSame(t); //prints 1 std::tuple<int, float, int> t2 = { 1, 1.0, 1}; std::cout << allSame(t2); //prints 0 std::tuple<int, int, int> t3 = { 1, 8, 1}; std::cout << allSame(t3); //prints 0 }
Demo
备注
如果您不关心这些值,那么用return true;替换第一个模板的主体就很简单了,如下面的modified demo所示。
return true;
ilmyapht4#
另一种变体:
template <typename... Ts> struct all_same_type : std::bool_constant<[](){ if constexpr (sizeof...(Ts) == 0) { return true; } else { using First = std::tuple_element_t<0, std::tuple<Ts...>>; return (std::is_same_v<First, Ts> && ...); } }()> { }; template <typename T> struct all_same_inner_type; template <typename... Ts> struct all_same_inner_type<std::tuple<Ts...>> : all_same_type<Ts...> {}; template <typename...Ts> constexpr bool all_same_inner_type_v = all_same_inner_type<Ts...>::value;
4条答案
按热度按时间jei2mxaa1#
C++17解决方案与折叠表达式:
也许你想使用
std::is_same_v
的替代品/补充:std::is_convertible
,尽管您应该检查这两对,因为它不是对称的。std::swappable
在这个意义上可能是is_convertible
的对称版本。const float&
和float
被视为相等,则添加std::decay
。xxslljrj2#
当
std::tuple<A,B,C,D>
和std::tuple<B,C,D,A>
是相同类型时,元组std::tuple<A,B,C,D>
的类型都相同。Output:
q9rjltbz3#
下面是使用fold expressions和lambda expression的方法:
Demo
备注
如果您不关心这些值,那么用
return true;
替换第一个模板的主体就很简单了,如下面的modified demo所示。ilmyapht4#
另一种变体:
Demo