基于类成员的存在/缺席专门化C++模板?

drw*_*owe 8 c++ templates type-traits template-specialization

考虑以下:

struct A {
  typedef int foo;
};

struct B {};

template<class T, bool has_foo = /* ??? */>
struct C {};
Run Code Online (Sandbox Code Playgroud)

我想专门ç,因此C <A>得到一个专业化和C <B>获取其他,基于存在或不存在类型名称的T :: foo中.这可能是使用类型特征或其他模板魔术吗?

问题是我尝试的所有内容在实例化C <B>时都会产生编译错误,因为B :: foo不存在.但这就是我想要测试的!


编辑:我认为ildjarn的答案更好,但我终于提出了以下C++ 11解决方案.男人是hacky,但至少它很短.:)

template<class T>
constexpr typename T::foo* has_foo(T*) {
  return (typename T::foo*) 1;
}
constexpr bool has_foo(...) {
  return false;
}
template<class T, bool has_foo = (bool) has_foo((T*)0)>
Run Code Online (Sandbox Code Playgroud)

ild*_*arn 6

另一种(C++ 03)方法:

template<typename T>
struct has_foo
{
private:
    typedef char no;
    struct yes { no m[2]; };

    static T* make();
    template<typename U>
    static yes check(U*, typename U::foo* = 0);
    static no check(...);

public:
    static bool const value = sizeof(check(make())) == sizeof(yes);
};

struct A
{
    typedef int foo;
};

struct B { };

template<typename T, bool HasFooB = has_foo<T>::value>
struct C
{
    // T has foo
};

template<typename T>
struct C<T, false>
{
    // T has no foo
};
Run Code Online (Sandbox Code Playgroud)