简体   繁体   English

如何在类中测试typename?

[英]How to test for typename in class?

In a class template Foo I want to check if the template parameter provides a type named Bar . 在类模板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.
}

Since I want to combine this with other properties I want a hasBar metafunction. 由于我想将它与其他属性结合起来,我想要一个hasBar元函数。 So I can combine the boolean values and then use std::enable_if . 所以我可以组合布尔值,然后使用std::enable_if

I tried to understand and use SFINAE but failed: 我试图理解并使用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 is always false. hasBar<TypeA>::value始终为false。

What is the right way to define hasBar ? 定义hasBar的正确方法是什么?

Or is there some better approach then using to have a Bar? 或者是否有更好的方法然后using酒吧?

The simplest way would be to use the dependent type as the default value for an unnamed template parameter. 最简单的方法是使用依赖类型作为未命名模板参数的默认值。 Something like this: 像这样的东西:

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
}

This yields a pretty usable error message ( g++ 7.3.0 ): error: no type named 'Bar' in 'struct without_bar' . 这会产生一个非常有用的错误消息( g++ 7.3.0 ): error: no type named 'Bar' in 'struct without_bar'

You should add typename before T::Bar to specify that it's a nested type name, ie 您应该在T::Bar之前添加typename以指定它是嵌套类型名称,即

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

LIVE 生活

BTW: You can use std::void_t to make it simpler. 顺便说一句:您可以使用std::void_t使其更简单。 eg 例如

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 { };

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM