c++ - 如何在类里面测试类型名?

标签 c++ templates sfinae

在类模板中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元功能。所以我可以组合 bool 值,然后使用 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有一个酒吧?

最佳答案

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

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):错误:“struct without_bar”中没有名为“Bar”的类型

关于c++ - 如何在类里面测试类型名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54589357/

相关文章:

c# - 需要帮助理解 _set_security_error_handler()

c++ - 将 C++ 中的字符串拆分并处理为不同的变量

java - 我怎样才能使这个Java方法完全通用

c++ - 如果正确使用时它从不抛出,我是否应该声明一个方法 noexcept ?

c++ - SFINAE 检查继承的成员函数

c++ - std::declval 和未计算的表达式

c++ - 如何让 mciSendString 同时处理变量和空格?

c++ - 为什么OO概念接口(interface)在C++中不用关键字来表示?

c++ - templates, typename, lambda -> 依赖名称不依赖?

c++ - 如果传入任何类型的列表,则尝试禁用函数