C ++ boost函数重载模板

时间:2010-05-18 22:06:48

标签: c++ function boost

我无法弄清楚为什么这个段会给出未解决的重载函数错误(gcc版本4.3.4(Debian 4.3.4-6)):

#include <algorithm>
#include <boost/function.hpp>

// this does not work
int main1()
{
    typedef boost::function<const int&(const int&, const int&)> max;
    max m(&std::max<int>);
}

// this does not work
int main2() {
    typedef boost::function2<const int&, const int&, const int&> max;
    max m(static_cast<max>(&std::max<int>));
}

你能帮助我吗,谢谢

test.cpp: In function âint main()â:
test.cpp:7: error: no matching function for call to âboost::function2<const int&, const int&, const int&>::function2(<unresolved overloaded function type>)â
/usr/include/boost/function/function_template.hpp:747: note: candidates are: boost::function2<R, T1, T2>::function2(const boost::function2<R, T1, T2>&) [with R = const int&, T0 = const int&\
, T1 = const int&]
/usr/include/boost/function/function_template.hpp:739: note:                 boost::function2<R, T1, T2>::function2(boost::function2<R, T1, T2>::clear_type*) [with R = const int&, T0 = cons\
t int&, T1 = const int&]
/usr/include/boost/function/function_template.hpp:707: note:                 boost::function2<R, T1, T2>::function2() [with R = const int&, T0 = const int&, T1 = const int&]

max / min定义为

  template<typename _Tp>
    inline const _Tp&
    max(const _Tp& __a, const _Tp& __b)
    {
      // concept requirements
      __glibcxx_function_requires(_LessThanComparableConcept<_Tp>)
      //return  __a < __b ? __b : __a;
      if (__a < __b)
        return __b;
      return __a;
    }

我尝试了各种模板显式实例化,但似乎没有任何工作。 g ++ 4.1中出现相同的问题,但ICC中没有出现

这是有效的

#include <algorithm>
#include <boost/function.hpp>

namespace std_ {
    template<typename _Tp>
    inline const _Tp&
    max(const _Tp& __a, const _Tp& __b)
    {
        // concept requirements
        //return  __a < __b ? __b : __a;
        if (__a < __b)
            return __b;
        return __a;
    }
}

int main()
{
    typedef const int &T;
    typedef boost::function<T(T,T)> min_;
    //typedef const int&(*min_)(const int&, const int&);
    min_ m(::std_::max<int>);
}

和这个

#include <algorithm>
#include <boost/function.hpp>

int main()
{
    //typedef const int &T;
    //typedef boost::function<T(T,T)> min_;
    typedef const int&(*min_)(const int&, const int&);
    min_ m(::std::max<int>);
}

3 个答案:

答案 0 :(得分:6)

更新:这是一个已在gcc&gt; = 4.4中修复的gcc错误。 bugzilla。另外,用简化的测试用例修改了我的答案。

这个问题有两个组成部分:boost :: function采用函数指针和gcc bug的方式。

boost :: function - 您在问题中列出的错误消息有些奇怪;没有候选构造函数接受像函数地址这样的东西。深入了解boost :: function src,相关的构造函数是(省略了enable_if参数):

template<typename Functor>
function(Functor f) : base_type(f) {}

所以boost :: function在指定函数指针的类型时根本无法帮助你;如果函数重载,则必须强制转换地址以指定其类型。如果使用重载的函数地址,则无法实例化上述模板,因此相应的构造函数不会显示在错误消息中。

gcc bug - 如果再次查看stl_algobase.h标题,您会看到有两个名为max的模板,一个两个param版本和一个param版。这应该不是你的代码问题,对吧?术语&max<int>应该实例化单个param版本并获取其地址。然而,事实并非如此。您可以在简化(无标题)测试用例中看到问题:

template <class T>
const T& max(const T& x, const T& y){
   return x > y ? x : y;
}

template <class T, class C>
const T& max(const T& x, const T& y, C comp){
   return comp(x, y) ? y : x;

}

template <class R, class A0, class A1>
struct functor{
   template <class F>
   functor(F f) : f(f) {}
   R (*f)(A0, A1);
};

int main(void){
   functor<const int&, const int&, const int&> func(&max<int>);
   return 0;
}

上面的代码导致unresolved overloaded function type与gcc 4.3.4。修复方法是删除template <class T, class C> max(...){...}定义或在函数地址周围添加static_cast<const int& (*)(const int&, const int&)>(...)。我猜这个问题与标准规定的部分显式参数规范的错误应用有关。它允许您省略尾随模板参数来执行诸如指定返回值类型而不是参数类型的操作。也就是说,当编译器只应实例化完全指定的模板时,编译器将实例化两个模板。尽管如此,因为该错误已在gcc&gt; = 4.4中修复。

因为不应该攻击stl_algobase.h;),Vicente建议的工作是正确的,即将函数指针强制转换为所需的函数指针类型const int& (*)(const int&, const int&)。在你的代码中,强制转换不起作用,因为正如GMan指出的那样,你正在转换为boost :: function&lt; ...&gt;,它没有解决函数指针歧义的问题。

答案 1 :(得分:5)

要批评代码,没有理由static_cast。考虑所有演员要做的就是使用boost::function2的构造函数创建一个新的boost::function2,然后将它复制到m。只需直接构建到m

#include <algorithm>
#include <boost/function.hpp>

int main()
{
    typedef boost::function2<const int&, const int&, const int&> max;
    max m(&std::max<int>);
}

最后,boost::function的首选语法是:

#include <algorithm>
#include <boost/function.hpp>

int main()
{
    typedef boost::function<const int&(const int&, const int&)> max;
    max m(&std::max<int>);
}

n-ary特定类用于较旧的编译器支持。

答案 2 :(得分:3)

std :: max模板函数的定义似乎是一个问题,gcc&lt;的发布4.4

使用gcc-4.4.0和msvc Express9可以正常工作。

以下也适用于gcc-3.4和gcc-4.3

int main1()
{
    int res = std::max(1,2);
    typedef boost::function<const int&(const int&, const int&)> max;
    max m(static_cast<const int&(*)(const int&, const int&)>(std::max<int>));

    return 0
}