C++ 是否可以检查是否已使用特定模板参数实例化了类型?
不太确定我的术语是否100%正确,因此代码如下: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) 返回包含_
模板
结构空{};
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
}