Fra*_*ank 23 c++ templates sfinae enable-if
是否可以写一个类型的特点,它的值是所有常见的STL结构真(例如vector
,set
,map
,...)?
首先,我想编写一个类型特征,对于a vector
和false 都是如此.我试过这个,但它没有编译:
template<class T, typename Enable = void>
struct is_vector {
static bool const value = false;
};
template<class T, class U>
struct is_vector<T, typename boost::enable_if<boost::is_same<T, std::vector<U> > >::type> {
static bool const value = true;
};
Run Code Online (Sandbox Code Playgroud)
错误消息是template parameters not used in partial specialization: U
.
Nev*_*ore 30
看,另一个基于SFINAE的解决方案,用于检测类似STL的容器:
template<typename T, typename _ = void>
struct is_container : std::false_type {};
template<typename... Ts>
struct is_container_helper {};
template<typename T>
struct is_container<
T,
std::conditional_t<
false,
is_container_helper<
typename T::value_type,
typename T::size_type,
typename T::allocator_type,
typename T::iterator,
typename T::const_iterator,
decltype(std::declval<T>().size()),
decltype(std::declval<T>().begin()),
decltype(std::declval<T>().end()),
decltype(std::declval<T>().cbegin()),
decltype(std::declval<T>().cend())
>,
void
>
> : public std::true_type {};
Run Code Online (Sandbox Code Playgroud)
当然,您可以更改要检查的方法和类型.
如果你想只检测STL容器(它的意思std::vector
,std::list
等),你应该这样做此.
Dav*_*eas 16
你会说它应该比那简单......
template <typename T, typename _ = void>
struct is_vector {
static const bool value = false;
};
template <typename T>
struct is_vector< T,
typename enable_if<
is_same<T,
std::vector< typename T::value_type,
typename T::allocator_type >
>::value
>::type
>
{
static const bool value = true;
};
Run Code Online (Sandbox Code Playgroud)
......但我不确定这是否更简单.
在C++ 11中,您可以使用类型别名(我认为,未经测试):
template <typename T>
using is_vector = is_same<T, std::vector< typename T::value_type,
typename T::allocator_type > >;
Run Code Online (Sandbox Code Playgroud)
您的方法的问题是该类型U
在使用它的上下文中是不可推导的.
Fra*_*ank 14
实际上,经过一些反复试验,我发现它非常简单:
template<class T>
struct is_vector<std::vector<T> > {
static bool const value = true;
};
Run Code Online (Sandbox Code Playgroud)
我还是想知道如何写一个更通用的is_container
.我必须手动列出所有类型吗?
虽然这里的其他答案试图猜测一个类是否是一个容器可能对你有用,但我想向你介绍一个命名你想要返回的类型的替代方法.您可以使用它来构建任意is_(something)
特征类型.
template<class T> struct is_container : public std::false_type {};
template<class T, class Alloc>
struct is_container<std::vector<T, Alloc>> : public std::true_type {};
template<class K, class T, class Comp, class Alloc>
struct is_container<std::map<K, T, Comp, Alloc>> : public std::true_type {};
Run Code Online (Sandbox Code Playgroud)
等等.
您需要包含<type_traits>
您添加到规则中的任何类.
为什么不为is_container做这样的事情?
template <typename Container>
struct is_container : std::false_type { };
template <typename... Ts> struct is_container<std::list<Ts...> > : std::true_type { };
template <typename... Ts> struct is_container<std::vector<Ts...> > : std::true_type { };
// ...
Run Code Online (Sandbox Code Playgroud)
这样,用户可以通过部分专业化添加自己的容器.至于is_vector等,只是像我上面那样使用部分特化,但是只将它限制为一个容器类型,而不是很多.
归档时间: |
|
查看次数: |
15922 次 |
最近记录: |