16

この単純で無意味なコードを考えてみてください。

#include <iostream>

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

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

関数テンプレートの非常に単純な例です。A::testしかし、オーバーロードされたものに置き換えて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?
}

確かoperator()に、テンプレートに依存するパラメーターを受け取った場合、コンパイラーはテンプレートを推定する可能性があります。しかし、パラメーターなしのファンクターでテンプレート パラメーターを指定する適切な構文がわかりません。

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

明らかに、このコードはファンクター構文をバイパスするため機能します。

a.operator()<1>();

しかし、それはそれがファンクターであるという目的をちょっと無効にします:-P.

4

5 に答える 5

29

通話のみ可能

a.operator()<1>();

しかし、それはファンクターを使用していません。ファンクターはテンプレートでない operator() が必要です。これは、 varname()として呼び出せる必要があり、コードでは機能しないためです。

実際のファンクターにするには、コードをテンプレート クラスに変更します (ファンクターはクラスです)。

#include <iostream>

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

int main() {
    A<1> a;
    a();
}
于 2009-06-02T22:21:55.430 に答える
10

私が知っている「直接的な」方法は、次の方法以外にはありません。

 a.operator()<1>();

構文。コードを変更できる場合は、テンプレート パラメーターをクラスに移動するか、(boost|tr1)::bind を使用して (boost|tr1)::function オブジェクトを作成します。

于 2009-06-02T22:17:25.750 に答える
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;
}

テンプレートをいじる必要もありません。

于 2009-06-02T22:23:00.700 に答える
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>()();
}
于 2009-06-02T22:26:58.023 に答える
0

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

于 2009-06-02T22:24:06.003 に答える