如何测试 class 中的类型名称?
How to test for typename in class?
在 class 模板中 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
更好的方法来拥有酒吧?
您应该在 T::Bar
之前添加 typename
以指定它是嵌套类型名称,即
template<class T>
struct hasBar<T,decltype(std::declval<typename T::Bar>(),void())> : std::true_type {};
顺便说一句:您可以使用 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 { };
最简单的方法是使用依赖类型作为未命名模板参数的默认值。像这样:
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’
.
在 class 模板中 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
更好的方法来拥有酒吧?
您应该在 T::Bar
之前添加 typename
以指定它是嵌套类型名称,即
template<class T>
struct hasBar<T,decltype(std::declval<typename T::Bar>(),void())> : std::true_type {};
顺便说一句:您可以使用 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 { };
最简单的方法是使用依赖类型作为未命名模板参数的默认值。像这样:
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’
.