1

次の呼び出し可能オブジェクトがあるとします。

struct callable : public std::unary_function <void, void>
{
    void
    operator()() const
    {
        std::cout << "hello world" << std::endl;
    }
};  

astd::tr1::reference_wrapper<>はそれを介して呼び出します。

callable obj;
std::tr1::ref(obj)();

代わりに、 がoperator()引数を受け入れる場合:

struct callable : public std::unary_function <int, void>
{
    void
    operator()(int n) const
    {
        std::cout << n << std::endl;
    }
};  

std::tr1::bindreference_wrapper を呼び出し可能なラッパーとして受け入れます...

callable obj;
std::tr1::bind( std::tr1::ref(obj), 42 )();

しかし、これの何が問題なのですか?

std::tr1::ref(obj)(42);

g++-4.4 は次のエラーでコンパイルに失敗します:

test.cpp:17: error: no match for call to ‘(std::tr1::reference_wrapper<const callable>) (int)’
/usr/include/c++/4.4/tr1_impl/functional:462: note: candidates are: typename std::tr1::result_of<typename std::tr1::_Function_to_function_pointer<_Tp, std::tr1::is_function::value>::type(_Args ...)>::type std::tr1::reference_wrapper<_Tp>::operator()(_Args& ...) const [with _Args = int, _Tp = const callable]
4

3 に答える 3

2

何か問題があると確信できる理由は何ですか?私はこれがうまくいくと信じています:

#include <functional>
#include <iostream>

struct callable : public std::unary_function <int, void>
{
    void
    operator()(int n) const
    {
        std::cout << n << std::endl;
    }
};

int main() {     
    callable obj;
    std::tr1::ref(obj)(42);
    return 0;
}

少なくとも MS VC++ 9 では、問題なくコンパイルおよび実行されます。また、他のコンパイラでも動作しない理由がわかりません。

編集:TR1を見て、それを取り戻します。VC++ 9 で動作しますが、実際に動作する必要はないと思います。VC++ 9 は可変テンプレート引数をサポートしていないため、オーバーロードを介してこれをサポートしています。むしろ深く埋もれている ( <functional>includes <xawrap>、これが<xawrap0>[、次に、 include <xawrap1>] を含む) は、最大 10 個の引数の const バリアントへの参照と (重要なことに) 参照を生成するコードです。これが機能するのは、ほぼ確実に const バリアントへの参照が含まれているためです。

于 2010-05-15T15:20:42.487 に答える
2

g++-4.4 の tr1 reference_wrapper の実装には、次の演算子が装備されています。

  template<typename... _Args>
    typename result_of<_M_func_type(_Args...)>::type
    operator()(_Args&... __args) const
    {
      return __invoke(get(), __args...);
    }

参照によって引数を取ります。したがって、右辺値引数を渡して reference_wrapper を呼び出すことはできません。

std::tr1::ref(obj)(42);

代わりは:

int arg = 42;
std::tr1::ref(obj)(arg);

うまく動作します。

std::tr1::bind( std::tr1::ref(obj), 42 )() 

bind はコピーによって引数を取るため、機能します。

于 2010-05-15T15:58:02.507 に答える
0

まず第一に、null-ary関数に対するstd::unary_functionの使用は奇妙に見えます。"unary"=1つの引数を取ります。ArgType=voidを使用しても大丈夫かどうかはわかりません。

第二に、あなたはそれを後方に持っています。最初のテンプレートパラメータは引数の型に関するもので、2番目のパラメータは戻り型に関するものです。したがって、単項関数オブジェクトは次のように定義する必要があります。

struct callable : public std::unary_function<int,void>
{
    void operator()(int n) const
    {
        std::cout << n << std::endl;
    }
};
于 2010-05-15T15:13:25.733 に答える