检查成员函数时,SFINAE测试失败

时间:2017-08-07 11:47:07

标签: c++ templates sfinae

我尝试实现自己的SFINAE测试以确定模板变量的类型,在这种情况下,如果它是标量或向量:

#include <iostream>
#include <vector>

template <typename...>
using void_t = void;

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

template <typename T, template <typename> class Op>
struct detect<T, Op, void_t<Op<T>>> : std::true_type {};

template <typename T>
using toSize_t = decltype(std::declval<T>().size());

template <typename T>
using has_toSize = detect<T, toSize_t>;

int main(void)
{
    std::cout << "Hello World\n";
    std::vector<int> vec_a;
    std::vector<double> vec_b;
    double scal_a;
    int scal_b;
    std::cout << "scal_b is a vector: " << detect<int, has_toSize>{} << '\n';
    return 0;
}

现在,int肯定没有成员函数size(),但我仍然得到true而不是false值。为什么呢?

2 个答案:

答案 0 :(得分:3)

表达式:

FirebaseApp appCompanyA = FirebaseApp.getInstance("CompanyA");

非常奇怪。

请注意,detect<int, has_toSize>{} 是别名。写has_toSize始终是一个有效的表达式,其中has_toSize<T>是任意类型。因此,T检测到detect Op<T>Op的{​​{1}}是有效表达式。因此,输出为has_toSize

使用true的正确方法是:

detect

这意味着,您检查类型(在此特定情况下为std::cout << has_toSize<int>{} << std::endl; ^^^^^ check type )是否具有int成员函数。

答案 1 :(得分:1)

在C ++ 17中,您可以使用is_detected。这隐藏了所有SFINAE的一个很好的元函数。调用与其他答案类似。

#include <experimental/type_traits>

template < typename T >
using toSize_t = decltype(std::declval<T>().size());

template < typename T >
using has_toSize = std::experimental::is_detected< toSize_t, T >;

int main()
{
  static_assert( has_toSize<int>::value == false );
}