这被认为是SFINAE吗?
Is this considered SFINAE?
一周前我问了一个问题,问我如何能够简单地实例化一个类模板,只有当它接受的类型有一个特定的成员函数。在我的回答中,我得到了一个复杂的解决方案。但后来我试着自己做。我只是想知道这是否足以计算出给定类型T
有一个名为f
的空函数,它有0个参数。
#include <type_traits>
#include <utility>
template <typename T, typename = void>
struct has_f : std::false_type { };
template <typename T>
struct has_f<
T,
decltype(std::declval<T>().f(), void())> : std::true_type { };
template <typename T, typename = typename std::enable_if<has_f<T>::value>::type>
struct A { };
struct B
{
void f();
};
struct C { };
template class A<B>; // compiles
template class A<C>; // error: no type named ‘type’
// in ‘struct std::enable_if<false, void>’
如果是这样,为什么其他的答案在这个线程这么复杂?
是的,你已经用c++ 11 SFINAE最简单、最习惯的风格解决了这个问题。
请注意,您没有检查返回类型是否为void
,是否为非静态成员,是否没有参数。f
可以不带参数地调用。它甚至可以是函子
检查返回void
的虚成员非静态函数,使用
template <typename T>
struct has_f<T, decltype(void( static_cast< void (T::*)( void ) >( &T::f ) )) >
: std::true_type {};
template <typename T>
struct has_f<T, decltype(void( static_cast< void (T::*)( void ) const >( &T::f ) )) >
: std::true_type {};
相关文章:
- 为什么rand()的使用被认为是不好的
- 为什么 std::shared_ptr 被认为是"heavy"和"expensive",但 std::array "same perfprmance as plain (c-style) arrays
- 一个C头文件可以被认为是一个接口吗
- 为什么const char*和const char[]作为函数参数被认为是等价的
- 为什么12.0==11.999999999999999999被认为是真的
- 这会被认为是糟糕的编程实践吗?
- 为什么这被认为是恒定的?
- 抽象类/接口中的空方法是否被认为是一种好的做法?
- 如果我具有调用其其他实例之一的超载函数,它是否被认为是递归功能
- std::unique_ptr可以被认为是一个monad吗?
- C++ 指向类的指针和/或引用是否被认为是"movable"?
- 使用自定义宏来简化 cin 和 cout 语句等内容被认为是更好还是更差
- 使用成员函数更改对象或返回并分配它是否被认为是更好的做法?
- 我很难修复我认为是双重免费的东西
- 使用 #define 被认为是"bad practice"吗?
- 是一个被认为是不同类型的班级内部的正向声明
- 这被认为是有效的C 11还是C 14?还是GCC/Clang弄错了
- 为什么这个嵌套的 lambda 不被认为是 constexpr?
- 这被认为是SFINAE吗?
- "constexpr if"被认为是SFINAE吗?