在我继续尝试理解 std::enable_if 用法的过程中

In continuation of my attempts to understand std::enable_if usage

在这段代码中:

#include <iostream>
#include <cstdlib>
#include <type_traits>
#include <ios>

using std::enable_if;
using std::is_same;
using std::boolalpha;
using std::cout;
using std::endl;

template <typename T>
struct S {
  S(): t(static_cast<T>(NULL)) { }

  // void type() {
  //   cout << boolalpha;
  //   cout << is_same<T,int>::value << endl;
  // }

  template <typename enable_if<is_same<T,int>::value,T>::type>
  void type() {
    cout << boolalpha << true << endl;
  }

  T t;
};

int main(){
  S<int> s;
  s.type();
  return(0);
}

我成功编译并输出了作为非模板函数实现的方法 type();但是,对于使用 std::enable_if 作为模板函数实现的相同方法,我得到以下编译错误:

so_main.cpp:23:11: error: no matching member function for call to 'type'
        s.type();
        ~~^~~~
so_main.cpp:15:73: note: candidate template ignored: couldn't infer template argument ''
        template<typename enable_if<is_same<T,int>::value,T>::type>void type(){cout << boolalpha << true << endl;}
                                                                        ^
1 error generated.

我的理解是两种情况下实现的逻辑是相似的。 当方法是非模板时,T 的类型被证实为 int。但是,当 std::enable_if 用于为相同条件启用模板函数时(即 Tint),代码不会编译。

这是因为 SFINAE 仅适用于与模板本身相关的模板参数。标准调用 即时上下文 。在您的代码示例中,T 是 class 模板的模板参数,而不是成员函数模板的模板参数。

您可以通过为您的函数提供一个默认为 T 的虚拟模板参数并在其上使用 SFINAE 来规避此问题,如下所示:

template <typename U=T>
typename enable_if<is_same<U,int>::value>::type type() {
  cout << boolalpha << true << endl;
}