C++ 是否可以检查是否已使用特定模板参数实例化了类型?

C++ 是否可以检查是否已使用特定模板参数实例化了类型?,c++,templates,c++17,variadic-templates,template-meta-programming,C++,Templates,C++17,Variadic Templates,Template Meta Programming,不太确定我的术语是否100%正确,因此代码如下: 模板 结构空{}; int main(){ 使用T=空; //如何检查T是否包含双精度? 返回0; } 因此,这是专门针对接受多个模板类型的类型的。理想情况下,这也是在编译时进行的。如果不需要该类型的对象,则可获得额外点数 我能得到的最接近的结果是: 模板 constexpr bool包含_type(){ 如果constexpr(std::is_same_v) 返回true; 否则,如果constexpr(sizeof…(U)>0) 返回包含_

不太确定我的术语是否100%正确,因此代码如下:

模板
结构空{};
int main(){
使用T=空;
//如何检查T是否包含双精度?
返回0;
}
因此,这是专门针对接受多个模板类型的类型的。理想情况下,这也是在编译时进行的。如果不需要该类型的对象,则可获得额外点数

我能得到的最接近的结果是:

模板
constexpr bool包含_type(){
如果constexpr(std::is_same_v)
返回true;
否则,如果constexpr(sizeof…(U)>0)
返回包含_type();
其他的
返回false;
}
模板
constexpr bool是否包含类型(TypeToCheck){
如果constexpr(sizeof…(T)>0)
返回包含_type();
其他的
返回false;
}
constexpr bool does_contain_double=doubj_contain_type(T{});

包含C++语法,我以前从未见过,但是它是有效的。如果它不需要

t{}
对象,那么它将非常整洁。也许看起来有点理智。

不知道你到底想要什么。。。但我想是这样的

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{});
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建议:谢谢!)

模板
结构对象是否包含类型
{
模板
静态constexpr自动值=(std::is_same_v | |…);
};
// ...
使用T=空;
constexpr auto x=对象是否包含类型::值;

这个问题已经得到了回答,但如果您想在某个时候打开
空的
层,我将加入一个扩展

#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
}
#包括
#包括
//非模板类型
模板
结构包含\u类型{
静态constexpr bool value=(std::is_same_v | | |……);
};
//模板类型
模板
结构包含\u类型{
静态constexpr布尔值=
(std::is_same_v | | | |……)| |//如果“check”是模板化的
(包含_type::value | |…);//展开一个图层
};
//辅助变量模板
模板
inline constexpr bool contains_type_v=contains_type::value;
模板
结构空{};
int main(){
使用False=空;
使用True=空;
使用DoubleNestFalse=空;
使用DoubleNestTrue=空;

std::您可以用std::declval()替换
T{}
哦,对了,我读到了它,并认为有一天我会使用它。这一天有一些,谢谢。@eerorika-如果我没有错的话,用
|
折叠是
错误的,以防empy list。这太简单了,谢谢。遗憾的是,没有参数似乎是不可能的。但是用
std::declval
折叠不应该太简单丑陋。@Basti-添加了一个替代版本,以防您不想实例化
t
类型的对象(注意:代码未测试).我明白了。实际上这不是问题,我很好奇这是否可能。再次感谢。@Basti-如果您不需要类型为
t
的对象,那么最好使用检查类型本身的对象(IMHO)。不幸的是,需要更多的打字。
#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
}