跨平台方式从函数指针创建boost :: function

时间:2011-12-19 15:33:59

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

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

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

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

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我得到了#34;没有匹配功能&#34;错误。看来:

在MSVC boost::remove_pointer< bool (*)() >::typebool ()

但是在GCC 4.3上:boost::remove_pointer< bool (*)() >::typebool ()()

因此,在GCC上,不存在适当的MakeFunction模板。

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

2 个答案:

答案 0 :(得分:2)

您可以创建类型推导制造商功能模板:

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的预处理器黑客来模拟它们(例如,请参阅pretty printer source code)。

答案 1 :(得分:1)

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

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

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