如何测试类类型名?

问题描述 投票:2回答:2

在类模板Foo我想检查模板参数提供了一个名为Bar类型。

struct TypeA {using Bar = int;};
struct TypeB {};
template<class T>Foo{};

void main(){
  Foo<TypeA> a; // I want this to compile
  Foo<TypeB> b; // I want this to not compile, but print a nice message.
}

因为我想这与其他属性结合在一起我想hasBar元函数。所以,我可以结合布尔值,然后使用std::enable_if

我试图理解和使用SFINAE但失败:

template<class T, class Enable = void>struct hasBar : std::false_type {};

template<class T>
struct hasBar<T,decltype(std::declval<T::Bar>(),void())> : std::true_type {};

hasBar<TypeA>::value永远是假的。

什么是定义hasBar正确的方式?

或者是有一些更好的方法,然后using有一个酒吧?

c++ templates sfinae
2个回答
3
投票

您应该添加typename T::Bar之前指定,这是一个嵌套的类型名称,即

template<class T>
struct hasBar<T,decltype(std::declval<typename T::Bar>(),void())> : std::true_type {};

LIVE

BTW:您可以使用std::void_t,使其更简单。例如

template< class, class = std::void_t<> >
struct hasBar : std::false_type { };

template< class T >
struct hasBar<T, std::void_t<typename T::Bar>> : std::true_type { };

4
投票

最简单的方法是使用依赖类型的默认值未命名的模板参数。事情是这样的:

struct with_bar { using Bar = int; };
struct without_bar { };

template <typename T, typename = typename T::Bar>
struct bar_detector { };

int main() {
  bar_detector<with_bar>();
  bar_detector<without_bar>(); // won' compile
}

这产生了非常有用的错误消息(g++ 7.3.0):error: no type named ‘Bar’ in ‘struct without_bar’

© www.soinside.com 2019 - 2024. All rights reserved.