【问题标题】:SFINAE-test fails when checking for member function检查成员函数时 SFINAE 测试失败
【发布时间】:2017-08-08 10:34:16
【问题描述】:

我尝试实现自己的 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 值。为什么?

【问题讨论】:

  • 你的意思是写.. &lt;&lt; has_toSize&lt;int&gt;{}
  • 那行得通,但我举了那个例子:coliru.stacked-crooked.com/a/7eae9c76232a2d20,它就是我写的。
  • 但该示例没有像您的 has_toSize 这样的别名。如果您要写detect&lt;int, toSize_t&gt;,它将像您的示例一样。你正在做的是使用detect 两次。

标签: c++ templates sfinae


【解决方案1】:

表达式:

detect<int, has_toSize>{}

很奇怪。

注意,has_toSize 是一个别名。写has_toSize&lt;T&gt; 始终是一个有效的表达式,其中T 是任意类型。因此,detect 检测到 Op&lt;T&gt;(其中Ophas_toSize)是一个有效的表达式。所以,输出是true

detect的正确使用方式是:

std::cout << has_toSize<int>{} << std::endl;
                       ^^^^^
                     check type

这意味着,您检查一个类型(在这种特殊情况下为int)是否具有size() 成员函数。

【讨论】:

    【解决方案2】:

    在 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 );
    }
    

    【讨论】:

      猜你喜欢
      • 2013-09-05
      • 2011-03-23
      • 1970-01-01
      • 1970-01-01
      • 2021-09-06
      • 1970-01-01
      • 2016-06-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多