当使用`std :: enable_if`时,如何避免写`:: value`和`:: type`? [cppx] [英] How can I avoid writing `::value` and `::type` when using `std::enable_if`? [cppx]
问题描述
注意:这是一个 问答 ,以便记录一种技术,其他人可能会发现有用的,并为了可能变得意识到其他人’甚至更好的解决方案。请随意添加批评或问题作为评论。也可以随意添加额外的答案。 :)
在我的一些代码,即标题
rfc / cppx / text / String.h
发现以下神秘片段:
Note: This is a question-with-answer in order to document a technique that others might find useful, and in order to perhaps become aware of others’ even better solutions. Do feel free to add critique or questions as comments. Also do feel free to add additional answers. :)
In some of my code, namely the header
rfc/cppx/text/String.h
, I found the following mysterious snippet:
template< class S, class enable = CPPX_IF_( Is_a_< String, S > ) >
void operator! ( S const& )
{ string_detail::Meaningless::operation(); }
运算符!
a String
具有隐式转换为原始指针的类。所以我为这个类和派生类重载了运算符!
,以便无意中使用非支持的运算符将给出一个合适的编译错误,提到它是无意义的和无法访问。
The operator!
is in support of a String
class that has an implicit conversion to raw pointer. So I overload (among others) operator!
for this class and derived classes, so that inadvertent use of a non-supported operator will give a suitable compilation error, mentioning that it's meaningless and inaccessible. Which I think is much preferable to such usage being silently accepted with an unexpected, incorrect result.
CPPX_IF _
巨集支持Visual C ++ 12.0(2013)和更早版本,它发现C ++ 11 使用
大多超出了ken。对于一个更符合标准的编译器,我将只写…
The CPPX_IF_
macro supports Visual C++ 12.0 (2013) and earlier, which finds C++11 using
to be mostly beyond its ken. For a more standard-conforming compiler I would have written just …
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 _
c $ c> CPPX_IF _ ,其表达式更简洁易读
except that the If_
or CPPX_IF_
, and its expression, is much more concise and readable.
推荐答案
在C ++ 14中,变量模板使类型特征更容易看。将它与C ++ 11模板别名组合,并且所有cruft消失:
In C++14, variable templates make type traits a lot more comfortable to look at. Combine that with C++11 template aliases, and all the cruft disappears:
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
形式的Type别名实际上是作为C ++ 14标准库的一部分计划的,请参见[meta.type.synop]。
"Type" aliases of the form _t
are in fact planned as part of the standard library for C++14, see [meta.type.synop].
这篇关于当使用`std :: enable_if`时,如何避免写`:: value`和`:: type`? [cppx]的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!