c++ - 使用 `::value` 时如何避免写入 `::type` 和 `std::enable_if` ? [cppx]

标签 c++ templates c++11

注意:这是一个 question-with-answer 以记录其他人可能认为有用的技术,并可能了解其他人更好的解决方案。请随意添加批评或问题作为评论。也请随意添加其他答案。 :)


在我的一些代码中,即标题 rfc/cppx/text/String.h 中,我发现了以下神秘片段:

template< class S, class enable = CPPX_IF_( Is_a_< String, S > ) >
void operator!  ( S const& )
{ string_detail::Meaningless::operation(); }

operator! 支持 String 类,该类具有到原始指针的隐式转换。因此,我为此类和派生类重载了(除其他外)operator!,因此无意中使用了不受支持的运算符将给出适当的编译错误,并指出它没有意义且无法访问。我认为这比默默地接受这种意外的、不正确的结果更可取。

CPPX_IF_ 宏支持 Visual C++ 12.0 (2013) 及更早版本,它发现 C++11 using 大多超出其范围。对于一个更符合标准的编译器,我会写...

template< class S, class enable = If_< Is_a_< String, S > > >
void operator!  ( S const& )
{ string_detail::Meaningless::operation(); }

这看起来 std::enable_if,

template< class S, class enabled = typename std::enable_if< Is_a_< String, S >::value, void >::type >
void operator!  ( S const& )
{ string_detail::Meaningless::operation(); }

除了 If_CPPX_IF_ 及其表达式,简洁易读

我到底是怎么做到的?

最佳答案

在 C++14 中,变量模板使类型特征看起来更舒服。将它与 C++11 模板别名结合起来,所有繁琐的东西都消失了:

template <typename A, typename B>
bool is_base_of_v = std::is_base_of<A, B>::value;

template <bool B, typename T = void>
using enable_if_t = typename std::enable_if<B, T>::type;

用法:

template <typename B, typename D>
enable_if_t<is_base_of_v<B, D>, Foo> some_function(B & b, D & d) { /* ... */ }

_t 形式的“类型”别名实际上已计划作为 C++14 标准库的一部分,请参阅 [meta.type.synop]。

关于c++ - 使用 `::value` 时如何避免写入 `::type` 和 `std::enable_if` ? [cppx],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20945362/

相关文章:

c++ - 如何推断模板使用的 std::bind 对象的返回类型?

c++ - 接受const char *列表的字符串类构造函数

c++ - 从 BGL 图中提取邻接矩阵

c++ - 在 std::bind 中包装一个 lambda 以捕获 R 值

c++ - 显式特化中函数名称后的空尖括号

c++ - std::vector 与 std::initializer_list 问题:未定义的行为

c++ - 为什么 SFINAE (enable_if) 不适用于类模板的成员函数?

c++ - 使用 Visual C++ 在桌面上绘图

c++ - std::async with std::unique 不编译

c++ - 如何在链接列表中创建链接列表?