如何删除非containers参数
How to SFINAE out non-containers parameters
i具有一个模板功能,我只想适用于标准容器(或与标准容器兼容的容器,至少提供begin()
成员功能)。我正在以以下方式进行非族裔:
template<typename Container>
typename Container::value_type
f(const Container& c,
typename std::enable_if<
std::is_same<
decltype(*c.begin()),
typename Container::value_type
>::value
>::type* = nullptr)
{
// implementation here
}
std::is_same
和decltype
看起来不太优雅。有什么更好的方法吗?
ps:我在这里需要sfinae,因为我有不同的超载
template<typename Derived>
f(const Eigen::MatrixBase<Derived>& A)
,每当我尝试f(some_Eigen_matrix)
时,Container
过载最终被捡起,然后编译器会出现错误,因为类型缺少begin()
。
使用 void_t
,我们只能制作一个类型特征,以使其具有begin()
和end()
(以及您可能需要检查的其他任何内容,例如typename T::iterator
,您可以保持堆积的表达方式):
template <typename T, typename = void>
struct is_std_container : std::false_type { };
template <typename T>
struct is_std_container<T,
void_t<decltype(std::declval<T&>().begin()),
decltype(std::declval<T&>().end()),
typename T::value_type
>>
: std::true_type { };
然后就sfinae:
template <typename Container>
typename std::enable_if<
is_std_container<Container>::value,
typename Container::value_type
>::type
f(const Container& c) { .. }
另外,如果您真的想验证begin()
是否会给您T::iterator
(或者至少是它们平等可比性),则也可以做到这一点:
void_t<
decltype(begin(std::declval<T&>()) == std::declval<typename T::iterator>())
>
相关文章:
- 如何反转整数参数包
- 使用C++库在Android项目中修改gradle中的cmake参数,用于插入指令的测试
- 如何使用默认参数等选择模板专业化
- 模板参数替换失败,并且未完成隐式转换
- 具有默认模板参数的多态类的模板推导失败
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 函数调用中参数的顺序重要吗
- 部分定义/别名模板模板参数
- 模板-模板参数推导:三个不同的编译器三种不同的行为
- 使用不带参数的函数访问结构元素
- 基于另一个成员参数将函数调用从类传递给它的一个成员
- 如何在OMNET++中指定与命令行参数组合的输出文件名
- 如何使用Luacneneneba API正确读取字符串和表参数
- 在派生函数中指定void*参数
- 视图中的参数推导失败:take_while
- static_assert在宏中,但也可以扩展到可以用作函数参数的东西
- 使用指向成员的指针将成员函数作为参数传递
- 没有名称的C++模板参数
- 如何删除非containers参数