0

对于共享公共基类的类的以下代码段中的方法,我将不胜感激doIt(),如下所示

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

struct BarBase {};
struct Bar: BarBase {};

struct FooBase {};
struct Foo: FooBase {};

template <typename T>
struct Task
{
    // I'd like to specialize this method for classes with a common base class
    void doIt();        
};

// my attempt (does not compile)
template <typename T>
typename boost::enable_if<boost::is_base_of<FooBase, T> >::value
doIt() {
    std::cout << "Type is derived from FooBase\n";
}


int main()
{
    Task<Foo> f;
    f.doIt();
}
4

2 回答 2

1

您不能专门化模板类成员。您可以特化一个类,并且每个特化都是一个完全独立的类,它不会从非特化模板继承任何内容(它可能具有也可能没有非特化类的全部或部分成员)。

您还可以做的是在模板类中拥有一个模板成员函数,并对其进行专门化。所以你可以这样做:

template <typename T>
struct Task
{
    void doIt() { doItPriv<T>(); }
private:
    template<typename T1>
    void doItPriv();  
};

然后专攻doItPriv

于 2012-02-23T12:51:58.357 回答
0

根据这个答案,

SFINAE 仅在模板参数的参数推导中的替换使构造格式不正确时才有效。

这就是为什么你不能那样做:

template <typename T>
struct Task
{
    typename std::enable_if<std::is_base_of<FooBase, T>::value>::type doIt() {
        std::cout << "Type is derived from FooBase\n";
    }   

    typename std::enable_if<std::is_base_of<FooBase, T>::value == false>::type doIt()
    {
    }
};

这里doIt()不是模板,所以没有任何扣除。但您可以执行以下操作:

template <typename T1>
struct Task
{
    template <typename T>
    typename std::enable_if<std::is_base_of<FooBase, T>::value>::type doIt_() {
        std::cout << "Type is derived from FooBase\n";
    }   

    template <typename T>
    typename std::enable_if<std::is_base_of<FooBase, T>::value == false>::type doIt_()
    {
    }

    void doIt()
    {
        doIt_<T1>();
    }
};
于 2012-02-23T13:19:30.013 回答