C++ 模板 sfinae 错误

C++ template sfinae error

我有以下代码,我希望具有不同专业化的 TestEnableIf 具有不同的打印功能,但它没有按计划运行,错误如下。

struct myStruct;
struct notMyStruct;

template<typename T> struct TestEnableIf
{
        template<typename boost::enable_if< boost::is_same<myStruct, T>, int >::type = 0> void print()
        {
            std::cout << "this is my struct" << std::endl;
        }

        template<typename boost::enable_if< boost::is_same<notMyStruct, T>, int>::type=0> void print()
        {
            std::cout << "This is not my struct" << std::endl;
        }


};

static void testIsSame()
{

    TestEnableIf<myStruct> testEnable;
     testEnable.print();
     TestEnableIf<notMyStruct> testNotEnable;
     testNotEnable.print();
}

../src/testBoostGeneric.h:39:90: error: no type named ‘type’ in ‘struct boost::enable_if, int>’ template, int>::type=0> void print() ^ ../src/testBoostGeneric.h: In instantiation of ‘struct TestEnableIf’: ../src/testBoostGeneric.h:53:29:
required from here ../src/testBoostGeneric.h:34:90: error: no type named ‘type’ in ‘struct boost::enable_if, int>’ template, int >::type = 0> void print()

我不明白的是,如果 sfinae 意味着专业化失败不是错误,那么编译器为什么要抱怨失败?

SFINAE(顺便说一下,S 是 "substitution",不是 "specialization")对于成员函数来说,这种方式不适用于 class 类型参数。解决这个问题的一个简单方法是使用另一个模板参数:

template<
    typename TCopy = T
    typename boost::enable_if< boost::is_same<myStruct, TCopy>, int >::type = 0
> void print()
{
    std::cout << "this is my struct" << std::endl;
}

我从 STL's CppCon talk 中提取了这个。 TL;DW:当使用 class 的 T 类型参数时,编译器在实例化 class 模板时知道该类型是什么,并会检查 type 成员那个时间点。由于额外的 TCopy 类型参数是函数的局部参数,编译器在函数被实例化之前无法确定,此时 SFINAE 可以跳入以影响调用的重载集。