无法在VS .NET 2008中使用boost :: enable_if专门化成员函数模板

时间:2014-04-01 15:03:22

标签: c++ templates boost sfinae enable-if

我试图为两种不同类型的类专门化成员函数模板,如下所示:

#include <iostream>
#include <boost/utility/enable_if.hpp>

struct Wibble
{
    static const bool CAN_WIBBLE = true;
};

struct Wobble
{
    static const bool CAN_WIBBLE = false;
};

struct Foo
{
    //template<typename T>   // Why isn't this declaration sufficient?
    //void doStuff();

    template<typename T>
    typename boost::enable_if_c<T::CAN_WIBBLE,void>::type
    doStuff();

    template<typename T>
    typename boost::enable_if_c<!T::CAN_WIBBLE,void>::type
    doStuff();  
};

template<typename T>
typename boost::enable_if_c<T::CAN_WIBBLE,void>::type
Foo::doStuff()
{
    std::cout << "wibble ..." << std::endl;
}

template<typename T>
typename boost::enable_if_c<!T::CAN_WIBBLE,void>::type
Foo::doStuff()
{
    std::cout << "I can't wibble ..." << std::endl;
}

int main()
{
    Foo f;
    f.doStuff<Wibble>();
    f.doStuff<Wobble>();
}

GCC 4.8.2编译代码时,VS .NET 2008会发出错误消息:

error C2244: 'Foo::doStuff' : unable to match function definition to an existing declaration

        definition
        'boost::enable_if_c<!T::CAN_WIBBLE,void>::type Foo::doStuff(void)'
        existing declarations
        'boost::enable_if_c<!T::CAN_WIBBLE,void>::type Foo::doStuff(void)'
        'boost::enable_if_c<T::CAN_WIBBLE,void>::type Foo::doStuff(void)'

2 个答案:

答案 0 :(得分:3)

我建议使用代码调度:https://ideone.com/PA5PTg

struct Foo
{
    template<bool wibble>
    void _doStuff();

public:
    template<typename T>
    void doStuff()
    {
        _doStuff<T::CAN_WIBBLE>();
    }
};

template<>
void Foo::_doStuff<true>() { std::cout << "wibble ..." << std::endl; }

template<>
void Foo::_doStuff<false>() { std::cout << "I can't wibble ..." << std::endl; }

答案 1 :(得分:1)

您无法部分专门化(成员)功能模板。故事结束。

即使你可以,你应该有一个SFINAE友好的主要模板。在伪代码中:

template<typename T, typename Enable> void doStuff();
template<typename T> void doStuff<T, typename boost::enable_if_c<T::CAN_WIBBLE,void>::type>()
    { std::cout << "wibble ..." << std::endl; }
template<typename T> void doStuff<T, typename boost::enable_if_c<!T::CAN_WIBBLE,void>::type>()
    { std::cout << "I can't wibble ..." << std::endl; }

如果您准备好类模板(作为仿函数或只是定义非模板方法的类型......),您仍然可以使用此技术。

根据经验,对于函数模板,重载解析提供了静态多态,无需部分特化。参见

两者都是Herb Sutter