1

以下のテンプレート定義

template <typename Func, typename ReturnType, typename... Arguments>
class Command
{
public:
    Command(Func f) : m_func(f) { }
    ReturnType operator()(Arguments... funcArgs) { return m_func(funcArgs...); }
private:
    Func m_func;
};

次のテスト コードでインスタンス化すると、gcc 4.7.3 でエラー メッセージ (エラー: フィールド 'Command::m_func' が無効に宣言された関数型) が表示されます。

void testFunction(int i, double d)
{
    std::cout << "TestFunctor::operator()(" << i << ", " << d << ") called." << std::endl;
}

int main()
{
    void (&fRef)(int, double) = TestFunction;
    Command<void(int, double), void, int, double> testCommand(fRef);
}

このエラー メッセージは、address-of 演算子を指定せずに TestFunction を testCommand コンストラクターに渡す場合にも発生しますが、明示的に名前を付けた関数ポインターを渡すか、address-of 演算子を使用してパラメーターを渡すと消えます。このコードは、Modern C++ Design の第 5 章を考慮すると機能するはずだという印象を受けています。

関数への参照を格納できないが、関数ポインタは正常に機能する理由は何ですか? コマンドのコンストラクターにも引数としてファンクターを渡すことができるサポートを失うことなく、これをコンパイルできるようにする回避策はありますか?

4

2 に答える 2

2

C++11 にはstd::functionテンプレートが用意されています。関数ポインタをいじる必要はありません。

それらを参照渡し、コピー、移動でき、ラムダの保存にも使用できます。

std::function<void()> func = []() { std::cout << "Hi" << std::endl; };
于 2013-07-20T00:00:52.163 に答える