【问题标题】:Unifying container traits统一容器特征
【发布时间】:2015-03-27 04:06:50
【问题描述】:

我想构建能够回答is_vectoris_list 等问题的特征。问题是我必须制作每个版本的两个版本,即模板模板参数一:

template<template<class,class> class C>
struct is_vector1 : std::false_type { };

template<>
struct is_vector1<std::vector> : std::true_type { };

还有一个简单的模板参数:

template<class T>
struct is_vector2 : std::false_type { };

template<class T, class Alloc>
struct is_vector2<std::vector<T, Alloc>> : std::true_type { };

每个都将在不同的上下文中使用

// 1
is_vector1<std::list>::value; 

// 2
template<typename C>
auto func(C const& data) -> typename std::enable_if<is_vector2<C>::value>::type
{ /**/ }

有没有办法在两种情况下都只有一个版本可用?

注意

我没有制作基本模板的选项,一个可变参数模板,我在 C++11 之前的上下文中工作

【问题讨论】:

  • 在 C++11 之前的上下文中,带有尾随返回类型的替代函数定义语法是否无效?
  • @gha.st 1. 它只是为了举例 2. 我相信it is
  • @gha.st 是的,正确的。错误的复制粘贴,thnx 用于发现,我更正了它
  • 发生在我们最好的人身上 ;)

标签: c++ template-meta-programming typetraits


【解决方案1】:

可以通过重载函数模板来解决:

template<template<class, class> class T>
typename enable_if<!is_vector1<T>::value, char>::type is_vectorf();

template<template<class, class> class T>
typename enable_if<is_vector1<T>::value, char(&)[2]>::type is_vectorf();

template<typename T>
typename enable_if<!is_vector2<T>::value, char>::type is_vectorf();

template<typename T>
typename enable_if<is_vector2<T>::value, char(&)[2]>::type is_vectorf();

之后,只需添加一个简单的宏,使用sizeof 来转换函数的返回类型:

#define is_vector(T) ::std::integral_constant<bool, sizeof(is_vectorf<T>()) != 1>

用法相当明显,但如果它导致依赖名称,则可能需要typename。你可以看到an example here

请注意,::std::enable_if::std::integral_constant::std::declval 都来自 C++11 标准库,但使用 C++03 模拟它们相当容易。

【讨论】:

  • 所以给出一个在底层使用 SFINAE 的通用接口。不错!
猜你喜欢
  • 2014-11-04
  • 2019-04-25
  • 1970-01-01
  • 2021-05-06
  • 1970-01-01
  • 2022-04-26
  • 1970-01-01
  • 2012-09-03
  • 1970-01-01
相关资源
最近更新 更多