`std :: enable_if`是一个C ++元函数模板,参数`bool B`,`class T = void`,在标准C ++头文件`type_traits`中定义。如果`B`为真,则实例化类定义一个等于`T`的公共成员类型`type`;否则它没有。
使用`std::enable_if`时如何避免编写`::value`和`::type`? [cppx]
注意:这是一个问答题,旨在记录其他人可能认为有用的技术,并可能了解其他人更好的解决方案。欢迎大家补充
C++ 部分模板特化与 std::is_base_of 和 std::enable_if 相结合
假设我有两个类:可序列化和可打印。 因此,一个接受 Printable 的所有派生类的简单模板函数可能如下所示: 模板 假设我有两个班级:Serializable和Printable。 因此,接受 Printable 的所有派生类的简单模板函数可能如下所示: template <class T, class B = Printable, class = typename std::enable_if<std::is_base_of<B, T>::value>::type> void print(T value) { cout << value << endl; } 但是,如果我希望它也接受 Serializable 的所有派生类,同时我仍然可以控制函数体,这显然是行不通的: template <class T, class B = Printable, class = typename std::enable_if<std::is_base_of<B, T>::value>::type> void print(T value) { cout << value << endl; } template <class T, class B = Serializable, class = typename std::enable_if<std::is_base_of<B, T>::value>::type> void print(T value) { cout << value << endl; } // Error: Redefinition of ... 所以我认为这个问题的其余解决方案是模板专业化。 但我就是不知道如何结合 std::is_base_of 和 std::enable_if 来专门化模板。 希望有人愿意帮助我! 尝试逻辑运算符: std::enable_if<std::is_base_of<Serializable, T>::value || std::is_base_of<Printable, T>::value>::type 您可以轻松编写可变参数模板,例如: is_base_of_any<T, Printable, Serialiable, Googlable, Foobarable>::value 例如: template <typename T, typename ...> struct is_base_of_any : std::true_type {}; template <typename T, typename Head, typename ...Rest> struct is_base_of_any<T, Head, Rest...> : std::integral_constant<bool, std::is_base_of<T, Head>::value || is_base_of_any<T, Rest...>::value> { }; 如果您想要不同的实现: template <bool...> struct tag_type {}; template <typename T> void foo(T, tag_type<true, false>) { } // for Printable template <typename T> void foo(T, tag_type<false, true>) { } // for Serializable template <typename T> void foo(T x) { foo(x, tag_type<std::is_base_of<Printable, T>::value, std::is_base_of<Serializable, T>::value>()); } 最后一个重载(“面向用户”的重载)可能应该具有上述enable_if,以免创建过多的重载候选者。 您或许还可以使用如下标签制作一个可变参数 template <typename ...Bases>: tag_type<std::is_base_of<Bases, T>::value...> 比 Kerrek 的答案稍微少一点机械性,但恐怕没有更多的可读性: template <class T, typename std::enable_if<std::is_base_of<Printable, T>::value>::type* = nullptr> void print(const T& value) { std::cout << "printable(" << &value << ")\n"; } template <class T, typename std::enable_if<std::is_base_of<Serializable, T>::value>::type* = nullptr> void print(const T& value) { std::cout << "serializable(" << &value << ")\n"; } 观看它现场 ideone。 考虑一下: void print(const Printable& value) { cout << value << endl; } void print(const Serializable& value) { cout << value << endl; } 自然地,您将有适当的operator<<在右侧操作数中调用虚拟函数,这将执行实际的打印。
假设我有一个具有以下签名的类: 模板 A 级; 但是这个类的行为方式应该取决于其他一些参数,假设它是 va...
我试图根据类模板参数确定调用哪个版本的成员函数。我已经尝试过这个: #包括 #包括 模板<
在非模板成员函数上使用 std::enable_if 时出错[重复]
为什么此代码(M 类中的 fnc 值)无法通过 SFINAE 规则解析?我收到错误: 错误 1 错误 C2039:“类型”:不是以下成员 'std::tr1::
我正在尝试创建自己的“智能迭代器”,我想使用 SFINAE 根据迭代器的标签来创建一些运算符: 这是我的代码: 模板 我正在尝试创建自己的“智能迭代器”,并且我想使用 SFINAE 根据迭代器的标签创建一些运算符: 这是我的代码: template<class Iterator, class Predicat, class Tag> class RangeFilterIterator { public: RangeFilterIterator(Iterator begin, Iterator end, Predicat predicat) : mBegin(begin), mEnd(end), mPredicat(predicat) {} bool operator !=(RangeFilterIterator const &r) { return mBegin != r.mBegin; } typename Iterator::value_type &operator*() {return *mBegin;} RangeFilterIterator &operator++() { while(mBegin != mEnd && mPredicat(*mBegin++)); return *this; } template<class = std::enable_if_t<std::is_base_of<std::random_access_iterator_tag, Tag>::value>> RangeFilterIterator &operator+(std::size_t n) { while(n--) ++(*this); return *this; } template<class = std::enable_if_t<!std::is_base_of<std::random_access_iterator_tag, Tag>::value>> RangeFilterIterator &operator+(std::size_t n) = delete; private: Iterator mBegin, mEnd; Predicat mPredicat; }; template<typename Container, typename Predicate> auto RangeFilter(Container const &c, Predicate p) { using Iterator = RangeFilterIterator<typename Container::iterator, Predicate, typename Container::iterator::iterator_category>; Iterator begin(const_cast<Container&>(c).begin(), const_cast<Container&>(c).end(), p); Iterator end(const_cast<Container&>(c).end(), const_cast<Container&>(c).end(), p); return Range(begin, end); } 在RangeFilterIterator &operator+(std::size_t n) = delete行我收到错误:class member cannot be redeclared。 我对模板不太“擅长”,但我认为对于 SFINAE,只会“声明”两者之一。我错过了什么吗?还可以做别的吗? 好吧,当我使用返回类型参数而不是模板参数时,它可以工作。 template<class tag = Tag> std::enable_if_t<std::is_base_of<std::random_access_iterator_tag, tag>::value, RangeFilterIterator> &operator+(std::size_t n) { while(n--) ++(*this); return *this; } template<class tag = Tag> std::enable_if_t<!std::is_base_of<std::random_access_iterator_tag, tag>::value, RangeFilterIterator> &operator+(std::size_t n) = delete;
在我们的 C++14 代码库中,我们的模块有两种类型的扩展。将 A 组想象为启动时运行类型,将 B 组想象为关闭时运行类型。该模块只需提供所有扩展名的列表和
我遇到了有关正确使用enable_if和模板专业化的问题。 修改示例后(出于保密原因),下面是一个可比较的示例: 我...
无法用 std::enable_if 作为函数参数推导出模板参数
所以,我正在遵循此网页上某处代码设置的示例: http://eli.thegreenplace.net/2014/sfinae-and-enable_if/ 这是我所拥有的: 模板 void fun(const type...
当我尝试启用我的订阅时,会弹出一个窗口,提示我有余额要支付。我现在点击付款,然后它会将我重定向到另一个窗口,说所有余额都已支付。但是
是表达式`requires { typename enable_if_t<fun_v<T>>; }` 与任何元谓词 fun_v 的“根据定义”的 `fun_v<T>` 相同?
我正在阅读 Josuttis 的 C++20 完整指南,我想我已经吸收了下面模板中的一个子句 模板 requires 需要 { typename std::remove_const_...
最近,我在面试中被问到这个问题: 以下代码将调用哪个 Vector 构造函数? #包括 类迭代器{ 民众: 迭代器(int &x): ptr_(&am...
我想把我的模板中所有不和谐的enable_ifs去掉,用C++20的概念来代替,然而几乎没有任何关于概念的信息,而且语法的变化与我的任何源 ...
我写了一些东西,使用SFINAE在某些条件下不生成函数。当我直接使用元代码时,它能正常工作,但当我通过另一个间接使用该代码时, ...
我对 SFINAE 有基本的了解,而且我认为我理解许多关于 std::enable_if 如何利用它来选择函数模板特殊化的例子,但我很难理解......
为什么编译器说:'enable_if'不能用来禁用这个声明?
模板 使用 Enable_if = typename std::enable_if type; class Degree; template constexpr inline bool Is_Degree() { ...
我已经知道,你可以使用std::enable_if来启用(或不启用)一个类的方法,例如:template class Field { ... size_t offset(const std::array) &...
具有std::enable_if_t,静态成员初始化的模板类。
好吧,我自己找了半天,也没找到任何实际可行的答案,我得问一下:假设我有一个类(例子很拙劣,但希望现在已经足够好了)模板&...
避免运算符第一个参数上的float和non float发生模板运算符重载冲突
我有一种情况,我的模板模量运算符确实在浮点型和整型类型之间发挥很好的作用。我记得有一种方法可以使它在更广泛的范围内选择更具体的一个,...