3

在阅读 C++11 Standard时,我注意到只有在满足某个条件时才定义20.8.3三个s。typedef

通常如何编写这样的条件typedef

4

2 回答 2

3

做到这一点的方法是通过部分专业化。考虑以下实现enable_if(用于许多反射技巧,以及更多):

template <bool Condition, typename T>
struct enable_if {
    typedef T type;
};

template <typename T>
struct enable_if<false, T> { /* no typedef */ };

只有当我传入一个评估为常量的typedef enable_if<...>::type语句时才存在true。例如:

typename enable_if<std::is_same<int, int>::value, int>::type; // = int

typename enable_if<std::is_same<int, long double>::value, int>::type; // = error. No typedef inside.   

当您想为某种类型编写通用代码时,通常会使用此方法T,但前提是T具有某些属性,例如在 C++ 中,“替换失败不是错误”。例如

template <typename T, typename = enable_if<is_numeric<T>::value, int>::type>
struct Complex {
    // impl...
}; 

通过插入任何T非数字类型,我会得到一个编译器错误。它很脏,但它有效。

于 2013-05-01T19:46:42.057 回答
1

例如,像这样:

#include <type_traits>

namespace detail
{

template <class T, bool = std::is_integral<T>::value>
struct maybe_has_a_value_type_or_something_else_impl
{
    using value_type = T;
};

template <class T>
struct maybe_has_a_value_type_or_something_else_impl<T, false>
{
    using something_else = T;
};

} // namespace detail


template <class T>
struct maybe_has_a_value_type_or_something_else
    : public detail::maybe_has_a_value_type_or_something_else_impl<T>
{

};

class Foo
{

};

int main()
{
    maybe_has_a_value_type_or_something_else<int>::value_type          a;
    // maybe_has_a_value_type_or_something_else<int>::something_else   b;
    // maybe_has_a_value_type_or_something_else<Foo>::value_type       c;
    maybe_has_a_value_type_or_something_else<Foo>::something_else      d;
}

LLVM 标头中使用了类似的实现__functional_base

于 2013-05-01T17:31:22.277 回答