【问题标题】:Pointers to functions指向函数的指针
【发布时间】:2010-08-30 23:12:27
【问题描述】:

我必须将函数传递给指针。为此,我使用了 boost::function。捕获指针的函数针对不同的签名进行了重载。例如:

void Foo(boost::function<int ()>) { ... }
void Foo(boost::function<float ()>) { ... }
void Foo(boost::function<double ()>) { ... }

现在我想在那里传递一些类方法指针:

class test
{
   public:
      float toCall() { };
};

class Wrapper
{
  Wrapper() {
    test obj;
    Foo(boost::bind(&test::toCall, this));
  }
};


error: no matching function for call to ‘Foo(boost::_bi::bind_t<float, boost::_mfi::mf0<float, test>, boost::_bi::list1<boost::_bi::value<Wrapper*> > >)’
    note: candidates are: Foo(boost::function<float()>&)

【问题讨论】:

    标签: c++ pointers boost-bind boost-function


    【解决方案1】:

    Nonono 这行不通。因为boost::function&lt;...&gt; 有一个模板化的构造函数来接受任何和所有类型。稍后会检查与调用签名的兼容性。重载解决方案无法解决此问题。

    另外,我认为您想通过&amp;obj 而不是this。尝试显式转换:

    Foo(boost::function<float ()>(boost::bind(&test::toCall, &obj)));
    

    这实在是太丑了,所以你可能想引入一个 typedef

    void Foo(FloatHandler) { ... }
    ...
    FloatHandler f(boost::bind(&test::toCall, &obj));
    Foo(f);
    

    或者最终你可以使Foo 成为一个只接受任何可调用类型T 的模板。我怀疑这可能是最简单的,因为在一般情况下,我怀疑您不知道您需要转换到什么 boost::function&lt;...&gt;。想要返回std::complex&lt;&gt; 的人呢?所以...

    template<typename T>
    void Foo(T) { ... }
    ...
    Foo(boost::bind(&test::toCall, &obj));
    

    希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      排队

      Foo(boost::bind(&test::toCall, this));
      

      this 的类型为 Wrapper。但是bind在上面找不到toCall方法。

      这是一个固定版本(完整,在 g++ 4.3.2 上编译),这可能是您想要做的:

      #include <boost/bind.hpp>
      #include <boost/function.hpp>
      
      void Foo(boost::function<int()>) {}
      void Foo(boost::function<float()>) {}
      void Foo(boost::function<double()>) {}
      
      struct test {
        float toCall() {return 0.0f;}
      };
      
      int main(int,char**) {
        test obj;
        boost::function<float()> tgt=boost::bind(&test::toCall,obj);
        Foo(tgt);
        return 0;
      }
      

      正如 AndreyT 的回答所指出的,bind 的返回类型......有点奇怪,因此显式强制转换为适当的函数类型。

      【讨论】:

        【解决方案3】:

        boost::bind 不返回 boost::function 对象。它返回一个 unspecified 类型的对象,该对象可以用作具有相应数量参数的函子。

        虽然boost::function 可以从boost::bind 的结果进行转换构造,但这种情况下的重载决议对于C++ 来说“太复杂”了。 (删除了我的不好的例子,它并没有真正说明正确的问题)。

        【讨论】:

        • 对于 boost 功能,情况比这更邪恶。现在就像template&lt;typename T&gt; struct A { template&lt;typename U&gt; A(U); };that 在我看来是无法解决的 xD 请注意,如果您只有一个功能,您可以 转换。困难在于比较两个这样的转换序列。在 boost::function 的情况下,这是完全不可能的,而在你的情况下,这可能是可能的,但是对于过度分辨率来说太复杂了。
        • @Johannes Schaub:你是对的。我的例子说明了一个完全不同的问题:歧义而不是“不可解决”:)
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-04-26
        • 1970-01-01
        • 2013-04-10
        • 1970-01-01
        相关资源
        最近更新 更多