不太确定我的术语是否 100% 正确,所以代码如下:
template<class... Ts>
struct Empty { };
int main() {
using T = Empty<int, double>;
// How to check if T "contains" double?
return 0;
}
所以这是专门针对接受多种模板类型的类型。这也最好是在编译时。如果不需要该类型的对象,则加分。
我能得到的最接近的(使用 help)是这样的:
template <class check, class T, class... U>
constexpr bool contains_type(){
if constexpr (std::is_same_v<T, check>)
return true;
else if constexpr (sizeof...(U) > 0)
return contains_type<check, U...>();
else
return false;
}
template <class check, template<class> class TypeToCheck, class... T>
constexpr bool does_obj_contain_type(TypeToCheck<T...>) {
if constexpr (sizeof...(T) > 0)
return contains_type<check, T...>();
else
return false;
}
constexpr bool does_contain_double = does_obj_contain_type<double>(T{});
它包含我以前从未见过的 C++ 语法,但它有效。如果不需要 T{}
对象会很整洁。也许看起来更理智一些。
答案 0 :(得分:2)
不确定你到底想要什么......但我想是这样的
template <class check, template<class...> class TypeToCheck, class... T>
constexpr bool does_obj_contain_type(TypeToCheck<T...>) {
return (std::is_same_v<check, T> || ...);
}
// ...
using T = Empty<int, double>;
auto x = does_obj_contain_type<double>(T{});
但是如果您不能实例化类型为 T
的对象,这是一个问题。在这种情况下,我想您可以使用类/结构特化。
有点像
template <typename>
struct does_obj_contain_type;
template <template <typename...> class TTC, typename ... Ts>
struct does_obj_contain_type<TTC<Ts...>>
{
template <typename check>
static constexpr bool func ()
{ return (std::is_same_v<check, Ts> || ...); }
};
// ...
using T = Empty<int, double>;
constexpr auto x = does_obj_contain_type<T>::func<double>();
或者作为模板变量 value
更好(由 super 推荐:谢谢!)
template <template <typename...> class TTC, typename ... Ts>
struct does_obj_contain_type<TTC<Ts...>>
{
template <typename Check>
static constexpr auto value = (std::is_same_v<Check, Ts> || ...);
};
// ...
using T = Empty<int, double>;
constexpr auto x = does_obj_contain_type<T>::value<double>;
答案 1 :(得分:2)
问题已经得到解答,但如果您想在某个时候展开 Empty<>
的层,我将进行扩展。
#include <iostream>
#include <type_traits>
// non templated types
template<class check, class... Ts>
struct contains_type {
static constexpr bool value = (std::is_same_v<check, Ts> || ...);
};
// templated types
template <class check, template<class...> class TypeToCheck, class... Ts>
struct contains_type<check, TypeToCheck<Ts...>> {
static constexpr bool value =
(std::is_same_v<check, Ts> || ...) || // if "check" is templated
(contains_type<check, Ts>::value || ...); // unwrap one layer
};
// Helper variable template
template<class... Ts>
inline constexpr bool contains_type_v = contains_type<Ts...>::value;
template<class... Ts>
struct Empty { };
int main() {
using False = Empty<int, float, float, long double>;
using True = Empty<int, double, int>;
using DoubleNestFalse = Empty<Empty<int>, Empty<int, float>>;
using DoubleNestTrue = Empty<Empty<int>, Empty<double, float>>;
std::cout << std::boolalpha;
std::cout << contains_type_v<double, False> << '\n';
std::cout << contains_type_v<double, True> << '\n';
std::cout << contains_type_v<double, float> << '\n'; // false
std::cout << contains_type_v<double, int, double> << '\n'; // true
std::cout << contains_type_v<double, DoubleNestFalse> << '\n';
std::cout << contains_type_v<double, DoubleNestTrue> << '\n';
std::cout << contains_type_v<Empty<int>, DoubleNestTrue> << '\n'; // true
}