C++ 模板 sfinae 错误

标签 c++ templates boost sfinae

我有以下代码,我希望具有不同特化的 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 是“替代”,而不是“特化”)不适用于类类型参数。一个简单的解决方法是使用另一个模板参数:

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:当使用类的 T 类型参数时,编译器在实例化类模板时知道该类型是什么,并会在那个时间点检查 type 成员.由于额外的 TCopy 类型参数是函数的本地参数,编译器在函数被实例化之前无法确定,此时 SFINAE 可以跳入以影响调用的重载集。

关于C++ 模板 sfinae 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29171309/

相关文章:

用于最小可执行文件的 C++ Windows 编译器

c++ - 如何将 A<B<T>>* 解释为 A<C<T>>* 其中 B : public C<T>?

c++ - 如何在一个类的不同实例之间共享互斥量?

c++ - Boost asio http截止日期错误?

templates - C++/C++11 - 可变参数模板的 Switch 语句?

c++ - 警告在 WDK 构建 ("LNK4217: locally defined symbol _ imported in function _"中链接 boost 库)

c++ - CMake Tools for Visual Studio 2017 卡住解析

c++ - 模板相关的名称解析不应该找到没有链接的声明?

c++ - 如何强制 MIDL 编译器在 Visual Studio 2010 中使用 "C++ mode"而不是 "C mode"?

c++ - STATIC_ASSERTION_FAILURE 有什么作用?