因为没有人发布它,所以我正在添加一个基于我在这里学到的 bool 技巧的解决方案:
#include<type_traits>
#include<tuple>
template<bool...>
struct check {};
template<typename U, typename... T>
constexpr bool contains(std::tuple<T...>) {
return not std::is_same<
check<false, std::is_same<U, T>::value...>,
check<std::is_same<U, T>::value..., false>
>::value;
}
int main() {
static_assert(contains<int>(std::tuple<int, char, double>{}), "!");
static_assert(contains<char>(std::tuple<int, char, double>{}), "!");
static_assert(contains<double>(std::tuple<int, char, double>{}), "!");
static_assert(not contains<float>(std::tuple<int, char, double>{}), "!");
static_assert(not contains<void>(std::tuple<int, char, double>{}), "!");
}
就编译时性能而言,它比accepted solution 慢,但值得一提。
在 C++14 中,它会更容易编写。标准模板已经在 <utility> 标头中提供了您需要执行的所有操作:
template<typename U, typename... T>
constexpr auto contains(std::tuple<T...>) {
return not std::is_same<
std::integer_sequence<bool, false, std::is_same<U, T>::value...>,
std::integer_sequence<bool, std::is_same<U, T>::value..., false>
>::value;
}
这在概念上与 std::get 所做的相差不远(从 C++14 开始可用于类型),但请注意,如果 U 类型在 T... 中多次出现,则后者无法编译。
是否符合您的要求主要取决于实际问题。