3

基本クラスのメンバー関数を特殊化したいと考えています。ただし、コンパイルされません。コンパイルできる代替案を知っている人はいますか?

ここに例があります

struct Base
{
    template<typename T>
    void Foo()
    {
        throw "Foo() is not defined for this type";
    }
};

struct Derived : public Base
{
    template<>
    void Foo<int>() { cout << "Foo<int>()" << endl; } // compile error (cannot specialize members from a base class)

    template<>
    void Foo<double>() { cout << "Foo<double>()" << endl; }  // compile error (cannot specialize members from a base class)
};
4

3 に答える 3

2

最終的に、オーバーロードを使用して解決しました。

基本クラスは次のようになります

struct Base
{
    template<typename T>
    class OfType {}

    template<typename T>
    void Foo(OfType<T>) { static_assert(false, "Foo is not implemented for this type. Please look in the compiler error for more details."); }
};

struct Derived : public Base
{
    using Base::Foo;

    void Foo(OfType<int>) { // here comes logic for ints }
    void Foo(OfType<double>) { // here comes logic for doubles }
};

を使用するクライアント コードの例を次に示します。Foo()

template<typename S>
class ClassThatUsesFoo
{
    private: S s;

    template<typename T>
    void Bar(T item) 
    {  
        s.Foo(Base::OfType<T>());  // this is the code that uses Foo
        DoSomeStuffWithItem(item); 
    } 
};

void main()
{
    ClassThatUsesFoo<Derived> baz;
    baz.Bar(12); // this will internally use Foo for ints
    baz.Bar(12.0); // this will use Foo for doubles
    baz.Bar("hello world"); // this will give a verbose compile error
}
于 2012-10-18T11:11:20.080 に答える
0

への呼び出しを除いて、これはコンパイルされますFoo<char>()

#include <iostream>
#include <string>
using namespace std;

struct Base
{
    template<typename T>
    void Foo()
    {
        throw "Foo() is not defined for this type";
    }
};

struct Derived : public Base
{
    template<typename T> void Foo();
};

template<>
void Derived::Foo<int>() { cout << "Foo<int>()" << endl; }

template<>
void Derived::Foo<double>() { cout << "Foo<double>()" << endl; }

int main()
{
    Derived derived;

    // this is client code
    derived.Foo<int>(); 
    derived.Foo<double>(); 
    derived.Foo<char>();   // this throws
}

呼び出しが必要な場合、Foo<char>()または特に特化していないタイプの場合、これは機能します。すべてのタイプで機能する特殊化されていない実装が必要な場合は、次の非特殊化された実装も追加する必要がありFoo()ます。

template<typename T> 
void Derived::Foo() { cout << "generic" << endl; }
于 2012-10-17T15:35:37.493 に答える
0

アレックスとの議論に応えて(ジョン・ディブリングの回答のコメントを参照)、これが私が意味したことです(SSCCE):

#include <iostream>
using namespace std;

struct Base
{
    template<typename T>
    void Foo()
    {
        //static_assert(false, "Foo() is not defined for this type");
        throw "Foo() is not defined for this type";
    }
};
    // you can add as many specializations in Base as you like
    template <>
    void Base::Foo<char>()  {  cout << "Base::Foo<char>()" << endl;  }


struct Derived : public Base
{
    // just provide a default implementation of Derived::Foo
    // that redirects the call to the hidden Base::Foo
    template < typename T >
    void Foo()
    {  Base::Foo<T>();  }
};
    // the specializations for Derived
    template<>
    void Derived::Foo<int>() { cout << "Foo<int>()" << endl; }

    template<>
    void Derived::Foo<double>() { cout << "Foo<double>()" << endl; }


struct Derived_wo_specialization : public Base
{
    /* nothing */
};


int main()
{
    Derived d;
    d.Foo<char>();
    d.Foo<double>();

    Derived_wo_specialization dws;
    dws.Foo<char>();
    dws.Foo<double>();
}
于 2012-10-18T15:51:04.827 に答える