2012-01-07 7 views
2

私は関数がtemplate引数を通過できることを知っています。このようなクラスコンストラクタを渡すことはできますか?PassクラスC++でのテンプレート引数によるコンストラクタ

更新: 私はこれをしたい全体の理由は、私が(この場合はclass Aで)のallocに私がしたいクラスに変更

class A 
{ 
public: 
    A(){n=0;} 
    explicit A(int i){n=i;} 

private: 
    int n; 
}; 

class MemoryPool 
{ 
public: 
    void* normalMalloc(size_t size); 
    template<class T,class Constructor> 
    T* classMalloc(); 
}; 

template<class T,class Constructor> 
T* MemoryPool::classMalloc() 
{ 
    T* p = (T*)normalMalloc(sizeof(T)); 
    new (p) Constructor; // choose constructor 
    return p; 
} 

MemoryPool pool; 
pool.classMalloc<A,A()>(); //get default class 
pool.classMalloc<A,A(1)>(); 
をメモリプール内および任意のコードなしのコンストラクタを選択することができますです
+0

'A()は'テンプレート引数に引数を取らないと 'A'を返す、関数型を表しています。 – Xeo

+1

もう少し文脈を教えてください。この小さな情報しか与えられなかったので、私は自分自身に尋ねるでしょう: 'new_func 'の代わりに 'new A()'を直接使わないのはなぜですか?別の言い方をすると、 'new_func'があなたを買うのは何ですか?それは建設を抽象化していますか? – Andre

+0

@Andreなぜなら私はメモリプールでそれを使ってクラスをmallocできるからです。 – xucheng

答えて

5

あなたはコンストラクタを周りに渡すことはできませんが、工場出荷時のファンクタの周りに渡すことができます。

class A 
{ 
    int n; 

    A(int i) : n(i) {}; 

public: 

    static A* makeA(int i) 
    { 
     return new A(i); 
    } 
}; 

template<typename T, typename Factory> 
T* new_func(Factory factory) 
{ 
    return factory(); 
} 

#include <functional> 

int main() 
{ 
    new_func<A>(std::bind(&A::makeA, 0)); 
    new_func<A>(std::bind(&A::makeA, 1)); 
} 
+0

私がこれをやりたい理由は、メモリプール内のコンストラクタを選択して、割り当てたいクラス内でコードを変更しないことです。 – xucheng

4

あなたの全体の仮定が間違っています。その機能は必要ありません。

template<class T> 
T* new_func() 
{ 
    return new T; 
} 

new以降のものは、コンストラクタ参照ではなく型です。

+0

'new A()'と 'new A(1) ' – xucheng

+1

これは"コンストラクタを渡す "ことはありません。それは完全な引数リストを渡すでしょう。これは、通常の(メンバ)関数ポインタテンプレート引数では機能しません。もちろん、テンプレート引数ではなく、通常の関数引数として渡す必要があります。 「完璧なフォワーディング」を読んだり、尋ねたりします。 –

+1

'new_func()'にパラメータを追加します: 'T * new_func(int i = 0)'をコンストラクタに渡します。 – hmjd

0

この方法では、より良いと思い

template<class T, int n> 
struct Factory 
{ 
    static T* new_func() 
    { 
    return new T(n); 
    } 
}; 

template<class T> 
struct Factory<T,0> 
{ 
    static T* new_func() 
    { 
    return new T; 
    } 
}; 

T* t = Factory<T>::new_func(); //call default constructor 
T* t2 = Factory<T,2>::new_func(); //call constructor T(2) 
+0

私がこれをやりたい理由は、メモリプール内のコンストラクタを選択して、クラス内でコードを変更せずに割り当てることです。 – xucheng

+0

あなたのメモリプールクラスのFactoryスタイル。 – nttstar

+0

私はそれを使用するたびに迷惑ですか? mallocクラスのコンストラクタの引数が不明なので、新しいFactory構造体を記述する必要があります – xucheng

関連する問題