将std::type_Identity对象转换为类型
假设我们创建了两个type_of
函数,它们返回std::type_identity
,like:
template<auto VAR>
auto type_of() {
return std::type_identity<decltype(VAR)>{};
}
template<typename T>
auto type_of() {
return std::type_identity<T>{};
}
从std::type_identity
获取实际类型的方法似乎有点麻烦:
// this works
// both i1 and i2 are ints
decltype(type_of<int>())::type i1;
decltype(type_of<int{}>())::type i2;
有没有办法在上面的表达式中省去decltype
的需要,或者把它放在一个可重用的表达式中,以实现更好的效果,比如:
// can this work?
type_of<int>()::type i1;
type_of<int{}>()::type i2;
甚至更好:
// can this work??
type_of_t<int> i1;
type_of_t<int{}> i2;
注意:类型和非类型模板参数的专门化可能是一个方向,但不起作用(无法编译):
template<auto>
struct type_of;
template<typename T>
struct type_of<T> { // <== compilation error: type/value mismatch
using type = T;
};
template<auto VAR>
struct type_of<VAR> {
using type = decltype(VAR);
};
解决方案
从std::type_identity
对象can be encapsulated into the following expresion获取类型:
template<auto x>
using type = typename decltype(x)::type;
这将允许替换繁琐的表达式:
decltype(type_of<int>())::type i1;
decltype(type_of<int{}>())::type i2;
使用更简单的表达式:
type<type_of<int>()> i1;
type<type_of<int{}>()> i2;
仍需(然后type_of
type
),因为第一步可以得到类型或变量,这只适用于函数模板重载,则函数不能返回类型,所以返回一个需要模板表达式来提取内部类型的对象。
根据您要对类型执行的操作,代码可以变得更简单。
如果您只想创建该类型的对象,则可以将该对象的创建转发到函数:
template<auto VAR, typename... Args>
auto create_type_of(Args&&... args) {
return decltype(VAR){std::forward<Args>(args)...};
}
template<typename T, typename... Args>
auto create_type_of(Args&&... args) {
return T{std::forward<Args>(args)...};
}
auto i1 = create_type_of<int>(7);
auto i2 = create_type_of<int{}>(7);
从std::type_identity
can work以这种方式创建类型的一般情况:
template<auto VAR>
constexpr auto type_of() {
return std::type_identity<decltype(VAR)>{};
}
template<typename T>
constexpr auto type_of() {
return std::type_identity<T>{};
}
template<typename T, typename... Args>
auto create(std::type_identity<T>, Args&&... args) {
return T{std::forward<Args>(args)...};
}
auto i1 = create(type_of<int>(), 7);
auto i2 = create(type_of<int{}>(), 7);
请注意,整个过程只适用于可用作非类型模板参数的变量。有关不使用模板(但使用宏...)并因此适用于不能作为模板参数的变量的更通用方法,请参见this mind blowing neat answer!
相关文章