简体   繁体   English

C ++ boost函数重载模板

[英]C++ boost function overloaded template

I cannot figure out why this segment gives unresolved overloaded function error (gcc version 4.3.4 (Debian 4.3.4-6)): 我无法弄清楚为什么这个段给出了未解决的重载函数错误(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>));
}

can you help me, thanks 你能帮助我吗,谢谢

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 is defined as 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;
    }

I have tried all sorts of template explicit instantiation but nothing seems to work. 我尝试了各种模板显式实例化,但似乎没有任何工作。 Same problem appears with g++ 4.1 but not with ICC g ++ 4.1会出现同样的问题,但ICC却没有

this works 这很有效

#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>);
}

and this 还有这个

#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>);
}

Update: this is a gcc bug that has been fixed in gcc >=4.4. 更新:这是一个已在gcc> = 4.4中修复的gcc错误。 bugzilla . bugzilla Also, revised my answer with a reduced test case. 另外,用简化的测试用例修改了我的答案。

There are two components to this problem: the way boost::function adopts a function pointer and the gcc bug. 这个问题有两个组成部分:boost :: function采用函数指针和gcc bug的方式。

boost::function - There is something strange about the error message you listed in the question; boost :: function - 你在问题中列出的错误信息有些奇怪; there is no candidate constructor that accepts anything like a function address. 没有候选构造函数接受像函数地址这样的东西。 Digging into the boost::function src, the relevant constructor is (leaving out the enable_if argument): 深入了解boost :: function src,相关的构造函数是(省略了enable_if参数):

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

So boost::function doesn't help you out at all in specifying the type of a function pointer; 所以boost :: function在指定函数指针的类型时根本没有帮助你; if the function is overloaded the address must be cast to specify its type. 如果函数重载,则必须强制转换地址以指定其类型。 If an overloaded function address is used, the above template can't be instantiated, and therefore the appropriate constructor doesn't show up in the error message. 如果使用重载的函数地址,则无法实例化上述模板,因此相应的构造函数不会显示在错误消息中。

gcc bug - If you look at the stl_algobase.h header again, you'll see there are two templates named max, a two param version and a one param version. gcc bug - 如果你再次查看stl_algobase.h标题,你会看到有两个名为max的模板,一个两个param版本和一个param版本。 This shouldn't be a problem with you code though, right? 这应该不是你的代码问题,对吧? The term &max<int> should instantiate the single param version and take its address. 术语&max<int>应该实例化单个param版本并获取其地址。 However, that is not what happens. 然而,事实并非如此。 You can see the problem in the reduced (no header) test case: 您可以在简化(无标题)测试用例中看到问题:

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;
}

The above code results in a unresolved overloaded function type with gcc 4.3.4. 上面的代码导致了一个unresolved overloaded function type与gcc 4.3.4。 The fix is either to remove the template <class T, class C> max(...){...} definition or add a static_cast<const int& (*)(const int&, const int&)>(...) around the function address. 修复是删除template <class T, class C> max(...){...}定义或添加static_cast<const int& (*)(const int&, const int&)>(...)围绕功能地址。 I'm guessing the problem has to do with incorrect application of partial explicit parameter specification, which is specified by the standard. 我猜这个问题与标准规定的部分显式参数规范的错误应用有关。 It lets you leave out trailing template parameters to do things like specify a return value type and not the argument types. 它允许您省略尾随模板参数来执行诸如指定返回值类型而不是参数类型的操作。 That is, the compiler instantiates both template when it should only instantiate the fully specified template. 也就是说,当编译器只应实例化完全指定的模板时,编译器将实例化两个模板。 Its moot speculation though, since the bug has been fixed in gcc >= 4.4. 虽然它没有实际意义,因为bug已经在gcc> = 4.4中得到修复。

Since one shouldn't hack at stl_algobase.h ;) , the work around Vicente suggests is the correct one, namely cast the function pointer to the desired function pointer type const int& (*)(const int&, const int&) . 因为不应该破解stl_algobase.h;),Vicente建议的工作是正确的,即将函数指针强制转换为所需的函数指针类型const int& (*)(const int&, const int&) In your code, the cast doesn't work because, as GMan points out, you are casting to a boost::function<...>, which does nothing to resolve the function pointer ambiguity. 在你的代码中,强制转换不起作用,因为正如GMan指出的那样,你正在转换为boost :: function <...>,它没有解决函数指针的歧义。

To critique the code, there's no reason to static_cast that. 为了批评代码,没有理由static_cast那样做。 Consider all the cast is going to do is use the constructor of boost::function2 to make a new boost::function2 , then it will be copy-constructed into m . 考虑所有演员要做的是使用boost::function2的构造boost::function2来创建一个新的boost::function2 ,然后将它复制构造成m Just construct directly into 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>);
}

Lastly, the preferred syntax of boost::function is: 最后, 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>);
}

The n-ary specific classes are for older compiler support. n-ary特定类用于较旧的编译器支持。

It seems to be a problem with the definition of the std::max template function with releases of gcc < 4.4 对于std :: max模板函数的定义,gcc <4.4的发布似乎存在问题

With gcc-4.4.0 and msvc Express9 it works. 使用gcc-4.4.0和msvc Express9可以正常工作。

The following works also for gcc-3.4 and gcc-4.3 以下也适用于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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM