2009-06-02 8 views
13

このシンプルで無意味なコードを考えてみましょう。C++ファンクタと関数テンプレート

#include <iostream> 

struct A { 
    template<int N> 
    void test() { 
     std::cout << N << std::endl; 
    } 
}; 

int main() { 
    A a; 
    a.test<1>(); 
} 

非常に簡単な関数テンプレートの例です。しかし、A::testをオーバーロードされたoperator()に置き換えて、それをファンクタにする場合はどうすればいいですか? operator()はテンプレートに依存していたパラメータを取った場合

#include <iostream> 

struct A { 
    template<int N> 
    void operator()() { 
     std::cout << N << std::endl; 
    } 
}; 

int main() { 
    A a; 
    a<1>(); // <-- error, how do I do this? 
} 

確かに、コンパイラはおそらくテンプレートを導き出すことができます。しかし、パラメータのないファンクタでテンプレートパラメータを指定するための適切な構文を理解できません。

これを行う適切な方法はありますか?

a.operator()<1>(); 

が、それはちょっと、それはファンクタ:-Pであることの目的に反し:それはファンクタの構文をバイパスするので

明らかに、このコードは動作します。

a.operator()<1>(); 

構文:

+0

+1:コード難読化で使用するための奇妙な構文。 http://thc.org/root/phun/unmaintain.htmlに記載する必要があります:-) –

答えて

9

は、私が知っている以外の別の "直接的" な方法はありません。コードを変更することができたら、テンプレートパラメータをクラスに移動するか、(boost | tr1):: bindを使って(boost | tr1):: functionオブジェクトを作成します。

24

あなただけ

a.operator()<1>(); 

を呼び出すことができますが、それは数子を使用していないでしょう。 Functorは、として呼び出せなければならないので、テンプレート演算子()以外が必要です。varname()これはあなたのコードでは機能しません。

それ本当のファンクタは(ファンクタはクラスである)あなたのコードテンプレートクラスを変更するには:あなたはどのように私の知る限りでは、オブジェクトのインスタンスにテンプレートパラメータを渡すためにしようとしている

#include <iostream> 

template<int N> 
struct A { 
    void operator()() { 
     std::cout << N << std::endl; 
    } 
}; 

int main() { 
    A<1> a; 
    a(); 
} 
2

許可されていません。テンプレートパラメータは、テンプレート関数またはテンプレートオブジェクトに渡すことしかできません。

a.test < 1>(); a.operator()< 1>();それらがテンプレート関数として機能しているために機能します。

boost :: bind(boostライブラリをチェックアウト)を使って修正してください。

struct A { 
    void operator()(int n) { 
     std::cout << n << std::endl; 
    } 
}; 

int main(int argc, char* argv[]) { 
    A a; 
    boost::function<void()> f = boost::bind<void>(a, 1); 
    f(); // prints 1 

    return 0; 
} 

あなたはテンプレートを使用する必要はありません。

0

いいえ、周りにはありません。あなたが言ったように、演算子を明示的に(目的を破る)呼び出すか、テンプレート引数がコンパイラによって推測できる必要があります。

1

あなたは固まっています。

struct A { 
    template<int N> 
    struct B 
    { 
     void operator()() 
     { std::cout << N << std::endl; } 
    }; 

    template<int N> 
    B<N> functor() {return B<N>();} 
}; 

int main() 
{ 
    A a; 
    a.functor<1>()(); 
} 
関連する問題