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 に答える