【问题标题】:Cross-platform way to create a boost::function from function pointer从函数指针创建 boost::function 的跨平台方法
【发布时间】:2011-12-19 15:33:59
【问题描述】:

我一直在编写一些希望通过 boost::function 传递的模板。他们确定 boost::function 的参数,然后使用它来创建一个适当的类特化。例如,这是 0 个参数的模板:

template< class ReturnT >
MyFunctionPtr MakeFunction( boost::function< ReturnT (  ) > func )
{
    return MyFunctionPtr( new MyFunction< decltype( func ), ReturnT >( func ) );
}

作为一个捷径,我有另一个版本的 MakeFunction 模板,它接受一个函数指针并自动将它包装在适当类型的 boost::function 中:

template< class T >
MyFunctionPtr MakeFunctionFromPointer( T func )
{
    return MakeFunction( 
        boost::function< typename boost::remove_pointer<T>::type >( func )
        );
}

这允许我从函数指针创建而无需显式传递函数规范:

int something() { return 1; }
MakeFunctionFromPointer( &something );

在 MSVC 上这工作正常,但在 GCC 4.3 中我得到“无匹配函数”错误。看来:

在 MSVC 上 boost::remove_pointer&lt; bool (*)() &gt;::typebool ()

但在 GCC 4.3 上:boost::remove_pointer&lt; bool (*)() &gt;::typebool ()()

所以在 GCC 上不存在 MakeFunction 的适当模板。

有什么方法可以改变任一平台上 remove_pointer 输出的输出以匹配另一个?或者有没有其他方法可以解决这个问题?

【问题讨论】:

  • 也许可以试试boost::decay 而不是remove_pointer...
  • @KerrekSB 这似乎导致bool (*)()boost::function 不接受。
  • template &lt;typename T&gt; MakeFunctionFromPointer(T(*f)()) { return boost::function&lt;T()&gt;(f); } 怎么样?
  • @KerrekSB 是的,这行得通。我希望避免必须为每个不同数量的参数定义重载,但我猜这可能是不可避免的。如果您将此作为答案,如果没有更好的结果,我会接受。
  • 嗯,一般来说你可以使用可变参数模板...

标签: c++ templates visual-c++ gcc boost


【解决方案1】:

你可以创建一个类型推导的maker函数模板:

template <typename R>
boost::function<R()> make_function(R(*f)())
{ return boost::function<R()>(f); }

template <typename R, typename ...Args>
boost::function<R(Args...)> make_function(R(*f)(Args...))
{ return boost::function<R(Args...)>(f); }

如果您的编译器不支持可变参数模板,您可以使用 Microsoft 的预处理器 hack 之类的东西来模拟它们(例如,参见 pretty printer source code 的示例)。

【讨论】:

    【解决方案2】:

    您可以显式地将指针作为函数参数,并从中推断出函数类型:

    template< class T >
    MyFunctionPtr MakeFunctionFromPointer( T * func )
    {
        return MakeFunction( boost::function<T>( func ) );
    }
    

    更新:根据您在下面的评论,问题似乎是您在 MakeFunctionFromPointer 的定义中使用它来声明 MakeFunction 之后。只要在使用前声明所有函数,我的版本或您使用 boost::remove_pointer 的版本都可以。

    【讨论】:

    • 这似乎在 GCC 上遇到了同样的问题。 T 是bool ()()
    • 是的,这个简单的例子有效。它缺少我将生成的 boost::function 传递给MakeFunction( boost::function&lt; ReturnT () &gt; ) 的地方,这就是我的问题所在。
    • @obmarg:那里也有no problem(尽管我缺少真正的MyFunction 类型)。您能否发布一个可编译的示例来说明您遇到的问题?
    • ideone.com/Ro76v 显示了我遇到的问题。虽然现在我已经玩了一点,但这可能只是我声明函数的顺序。
    • @obmarg:这确实是问题所在,至少对于您在此处发布的代码而言。交换两个函数重载,或者在第一个之前声明第二个,可以解决问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-01
    • 1970-01-01
    • 2010-12-27
    • 2010-09-18
    相关资源
    最近更新 更多