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::bind接受一个 reference_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

g++-4.4的tr1reference_wrapper的实现配备了如下操作符:

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

它通过引用接受参数。因此不能通过 r 值参数调用 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 回答
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>包括<xawrap>,其中包括<xawrap0>[which, 反过来,包括<xawrap1>])是为最多 10 个参数生成引用和(重要的是)对 const 变体的引用的代码。几乎可以肯定的是,包含对 const 变体的引用允许它工作。

于 2010-05-15T15:20:42.487 回答
0

首先,将 std::unary_function 用于空元函数看起来很奇怪。"unary" = 接受一个参数。我不确定是否可以使用 ArgType=void。

其次,你有它倒退。第一个模板参数是关于参数类型的,第二个是关于返回类型的。所以,你的一元函数对象应该这样定义:

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