获取模板参数的typedef,否则,获取类型本身
Getting a typedef of a template parameter, or failing that, getting the type itself
我正试图从我定义的类(ValueType
typedef(中获取typedef所指向的类型。但是,当失败时,我希望它返回给定的类型(例如,如果我给它一个double
,我希望其返回一个double
(。这就是我目前所拥有的:
struct myClass { typedef double ValueType; };
template < typename V, typename U = typename V::ValueType>
struct base_type { typedef U type; };
template < typename V >
struct base_type< V, V > { typedef V type; };
static_assert( std::is_same < typename base_type< myClass >::type , double >::value,
"base_type doesn't work" ); //This works.
static_assert( std::is_same < typename base_type< double >::type , double >::value,
"base_type doesn't work" ); //This returns "error: 'double' is not a class, struct, or union type"
然而,这不起作用,第二个static_assert失败。显然,第二个定义从未被调用,但我不确定为什么(它肯定会比第一个更好地匹配(。
有什么想法吗?
或者
template < typename V, typename = void>
struct base_type { typedef V type; };
template < typename V >
struct base_type< V,
typename base_type<void, typename V::ValueType>::type > {
typedef typename V::ValueType type;
};
我们都喜欢这些粗鲁丑陋的SFINAE黑客:(
您必须使用一个函数来实现有效的SFINAE。
以下是C++11新功能的外观:
template <typename T> auto get_base_type(int) -> typename T::ValueType;
template <typename T> auto get_base_type(...) -> T;
template <typename T>
struct base_type { using type = decltype(get_base_type<T>(0)); };
来自维基百科以下内容适用于我,我认为它符合您的要求。
#include <type_traits>
template <typename T>
struct has_typedef_ValueType {
// Types "yes" and "no" are guaranteed to have different sizes,
// specifically sizeof(yes) == 1 and sizeof(no) == 2.
typedef char yes[1];
typedef char no[2];
template <typename C>
static yes& test(typename C::ValueType*);
template <typename>
static no& test(...);
// If the "sizeof" the result of calling test<T>(0) would be equal to the sizeof(yes),
// the first overload worked and T has a nested type named foobar.
static const bool value = sizeof(test<T>(0)) == sizeof(yes);
};
struct myClass { typedef double ValueType; };
template < class V, bool b = has_typedef_ValueType<V>::value >
struct base_type { typedef typename V::ValueType type; };
template < typename V>
struct base_type <V, false> { typedef V type; };
static_assert( std::is_same < typename base_type< myClass >::type , double >::value, "base_type doesn't work" ); //This works.
static_assert( std::is_same < typename base_type< double >::type , double >::value, "base_type doesn't work" ); //This returns "error: 'double' is not a class, struct, or union type"
int main() {}
#include <type_traits>
#include <utility>
template < typename V, typename=void>
struct base_type { typedef V type; };
template < typename V >
struct base_type<
V,
typename std::enable_if<
std::is_same<
typename V::ValueType,
typename V::ValueType
>::value
>::type
>
{
typedef typename V::ValueType type;
};
这是一种非常通用的技术。基本案例有一个额外的未命名模板参数,默认为void
。
特化用typename std::enable_if< expression >::type
代替void
,并且表达式既是有效的又是真的是有效的特化IFF。
在这种情况下,我做了一个简单的std::is_same< V::value_type, V::value_type >::value
。众所周知,在我自己的代码中,我编写了valid_type< typename V::value_type >::value
,它简单地说就是:
template<typename>
struct valid_type:std::true_type {};
一个永远真实的特质类。
现在,void
技巧有一些问题。但我觉得它很普通。
double
不会实例化您的专业化,因为只有当base_type
被传递两个类型并且两者相同时,才会调用该专业化。第二种类型是可选的,但当没有提供时,它会用默认的typename V::ValueType
填充,当然这对double::ValueType
来说是失败的。
为了完整起见,您的base_type<V, V>
专业化将被实例化为以下类型:
struct foo { typedef foo ValueType; };
static_assert(std::is_same<base_type<foo>::type, foo>::value, "Failed");
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- C++为构建时间获取QDateTime的可靠方法
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 如何使用 < 和 > 命令获取 c++ 中的输入和输出?
- 使用指针从C++中的数组中获取最大值
- 如何获取std::result_of函数的返回类型
- 如何在openssl-ecc中获取十六进制格式的私钥
- 使用Unreal C++获取VR耳机的世界位置/方向
- 获取日期异步信号安全吗?如果在信号处理程序中使用,它会导致死锁吗
- 从C字符串中获取奇怪的字符串长度
- 为什么我的for循环不能正确获取argv
- 从python中调用C++函数并获取返回值
- 如何获取一个数字的前3位
- 获取字符串的长度并将其分配给数组
- 无法获取菜单选择以运行函数.C++
- 数组长度,为什么从命令行获取时不能使用它?
- Boost Spirit,获取迭代器内部语义动作
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- 具有默认值的引用获取函数
- 获取模板参数的typedef,否则,获取类型本身