2016-12-01 9 views
1

具体的なファクトリをテンプレートファクトリクラスに変換しようとしています。以下は私が書いたものです。私はg ++(GCC)4.8.5で作業しています。テンプレートクラスのテンプレート関数を関数ポインタにする方法

g ++はerror: no matches converting function ‘create’ to type ‘using create_t = class Base* (*)() {aka class Base* (*)()}’という文句を言います。それは、文create_t pf = create<S>;が失敗したことを縫い合わせますが、私はそれが何であるか分かりません。

#include<iostream> 
#include<type_traits> 
class Base { 
public: 
    virtual ~Base() {}; 
    virtual void print() { 
     std::cout << "In Base." << std::endl; 
    } 
}; 

class Derived: public Base { 
public: 
    void print() { 
     std::cout << "In Derived." << std::endl; 
    } 
}; 


template<typename T> 
class Factory { 
public: 
    using create_t = T* (*)(); 

    template<typename S> 
    T* create() { 
     static_assert(std::is_base_of<T, S>::value, "S must be a derived of T."); 
     return new S(); 
    } 

    template<typename S> 
    void test() { 
     create_t pf = create<S>; 
     T * pt = pf(); 
     pt->print();                                                
     delete pt; 
    } 
}; 

int main() { 
    Factory<Base> base_factory; 
    base_factory.test<Derived>(); 
    return 0; 
} 

答えて

2

あなたはstaticキーワード欠場:staticせず、それは非静的メンバ関数ですが、その種類はT* (Factory::*)(); ですので、あなたが本当に非としてそれを必要とする場合

template<typename S> 
static T* create() { 
    static_assert(std::is_base_of<T, S>::value, "S must be a derived of T."); 
    return new S(); 
} 

Demo

を静的メンバー関数:

using self = Factory; 
using create_t = T* (self::*)(); 

template<typename S> 
T* create() { 
    static_assert(std::is_base_of<T, S>::value, "S must be a derived of T."); 
    return new S(); 
} 

template<typename S> 
void test() { 
    create_t pf = &self::create<S>; 
    T * pt = (this->*pf)(); 
    pt->print();                                                
    delete pt; 
} 

Demo

+0

ありがとう、それは動作します。しかし、非静的関数がなぜ機能しないのですか?非テンプレートプレーン版であればOKです。 –

関連する問題