此代码获取满足测试的第一个元组元素(在这种情况下,如果它派生<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p class="p1">The first paragraph in body.</p>
<p class="p1">The second paragraph in body.</p>
<p class="p2">The third paragraph in body.</p>
<p class="p2">The fourth paragraph in body.</p>
)。 我怎样才能static_assert只有一个满足该条件的元素可能存在?(很像C ++ 17的Base
如果提供的typename中存在多个元素,则无法编译。)< / p>
std::get<class>
答案 0 :(得分:1)
这是一种不太优雅,但与C ++ 11兼容的方式。
#include <iostream>
#include <tuple>
struct foo {
};
struct bar : foo {
};
template <std::size_t N, typename... T>
struct check_tuple;
template <std::size_t N, typename First, typename... Rest>
struct check_tuple<N, First, Rest...> : check_tuple<N+std::is_base_of<foo, First>::value , Rest...> {};
template <std::size_t N, typename First>
struct check_tuple<N, First> : check_tuple<N+std::is_base_of<foo, First>::value> {};
template <std::size_t N>
struct check_tuple<N> : std::false_type {};
template <>
struct check_tuple<1> : std::true_type {};
template <typename Types>
struct check_tuple_types;
template <typename... Types>
struct check_tuple_types<std::tuple<Types...>> : check_tuple<0, Types...> {};
int main() {
std::cout << check_tuple_types<std::tuple<int, long, bar>>::value;
return 0;
}
答案 1 :(得分:0)
如果我正确理解您和您的代码,那么此专业化适用于类型T0
通过您的测试时:
template<template<class...> class Test, class T0, class...Ts>
struct first_pass<Test, std::enable_if_t<Test<T0>::value>, T0, Ts...> {
using type = T0;
};
所以你找到了一种通过测试的类型,现在你想确保Ts
中还没有通过测试的类型?如果是,则可以添加以下实用程序:
template <bool... bs>
struct any_of : public std::false_type { };
template <bool b, bool... bs>
struct any_of<b, bs...> :
public std::conditional_t<b, std::true_type, any_of<bs...>> { };
然后使用它:
template<template<class...> class Test, class T0, class...Ts>
struct first_pass<Test, std::enable_if_t<Test<T0>::value>, T0, Ts...> {
static_assert(!any_of<Test<Ts>::value...>::value,
"multiple types pass the test");
using type = T0;
};
另外,我不熟悉C ++ 17,所以请考虑这是一种前C ++ 17方法(使用已有的代码)。