2010-05-18 35 views
9

Tôi không thể hiểu tại sao phân khúc này cho chưa được giải quyết lỗi chức năng quá tải (phiên bản gcc 4.3.4 (Debian 4.3.4-6)):C++ tăng chức năng quá tải mẫu

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

bạn có thể giúp tôi, cảm ơn

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 được định nghĩa là

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

tôi đã thử tất cả các loại instantiation rõ ràng mẫu nhưng nothi ng dường như làm việc. Cùng một vấn đề xuất hiện với g ++ 4.1 nhưng không phải với ICC

làm việc này

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

và điều này

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

Tính năng này có hoạt động không có 'static_cast' hoặc với lớp' function' chung không? – GManNickG

+0

@GMan không, không hoạt động mà không có tĩnh đúc (đó là dấu hiệu của sự tuyệt vọng). Lớp chức năng chung là gì? – Anycorn

+0

Những gì bạn có. Tôi có nghĩa là chung chung là "không cụ thể cho một n cụ thể". (Tức là, "hàm" là tổng quát hơn thì "hàm2"). – GManNickG

Trả lời

6

Cập nhật: đây là lỗi gcc đã được cố định trong gcc> = 4.4. bugzilla. Ngoài ra, sửa đổi câu trả lời của tôi với một trường hợp thử nghiệm giảm.

Có hai thành phần cho vấn đề này: cách tăng :: chức năng sử dụng con trỏ hàm và lỗi gcc.

boost :: function - Có điều gì đó lạ về thông báo lỗi bạn đã liệt kê trong câu hỏi; không có hàm tạo ứng cử viên nào chấp nhận bất cứ thứ gì như địa chỉ hàm. Đào vào tăng :: chức năng src, các nhà xây dựng có liên quan được (rời ra lập luận enable_if):

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

Vì vậy, tăng cường chức năng :: không giúp bạn ra ở tất cả các quy định cụ thể các loại của một con trỏ hàm; nếu hàm bị quá tải thì địa chỉ phải được gán để chỉ định kiểu của nó. Nếu một địa chỉ hàm quá tải được sử dụng, mẫu trên không thể được khởi tạo, và do đó hàm tạo thích hợp không hiển thị trong thông báo lỗi.

gcc lỗi - Nếu bạn nhìn vào tiêu đề stl_algobase.h một lần nữa, bạn sẽ thấy có hai mẫu tên là max, một phiên bản hai param và một phiên bản một param. Tuy nhiên, đây không phải là vấn đề với mã của bạn, đúng không? Thuật ngữ &max<int> sẽ khởi tạo phiên bản đơn lẻ và lấy địa chỉ của nó. Tuy nhiên, đó không phải là những gì xảy ra. Bạn có thể thấy vấn đề trong trường hợp kiểm tra đã giảm (không có tiêu đề):

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

Mã trên dẫn đến unresolved overloaded function type với gcc 4.3.4. Khắc phục là xóa định nghĩa template <class T, class C> max(...){...} hoặc thêm static_cast<const int& (*)(const int&, const int&)>(...) xung quanh địa chỉ hàm. Tôi đoán vấn đề phải làm với ứng dụng không chính xác của đặc tả tham số một phần rõ ràng, được xác định bởi tiêu chuẩn. Nó cho phép bạn bỏ qua các tham số mẫu theo sau để thực hiện những việc như chỉ định kiểu giá trị trả lại chứ không phải kiểu đối số. Tức là, trình biên dịch khởi tạo cả hai khuôn mẫu khi nó chỉ nên khởi tạo mẫu được chỉ định đầy đủ. Mặc dù suy đoán của nó là do lỗi đã được sửa trong gcc> = 4.4.

Vì không nên hack tại stl_algobase.h;), công việc xung quanh Vicente đề xuất là đúng, cụ thể là đưa con trỏ hàm tới loại con trỏ hàm mong muốn const int& (*)(const int&, const int&). Trong mã của bạn, các diễn viên không hoạt động bởi vì, như GMan chỉ ra, bạn đang đúc để tăng :: chức năng < ...>, mà không có gì để giải quyết sự mơ hồ hàm con trỏ.

5

Để phê bình mã này, không có lý do gì để static_cast đó. Hãy xem xét tất cả các diễn viên sẽ làm là sử dụng các nhà xây dựng của boost::function2 để thực hiện một mới boost::function2, sau đó nó sẽ được sao chép xây dựng thành m. Chỉ cần xây dựng trực tiếp vào m:

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

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

Cuối cùng, cú pháp ưa thích của boost::function là:

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

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

Các lớp cụ thể n-ary là dành cho hỗ trợ biên dịch cũ.

+0

cùng một vấn đề, tôi đã thử điều đó trước đây. Tôi cũng đã thử phong cách mới (đầu tiên). Tôi đã đăng lỗi biên dịch – Anycorn

+0

@aaa: Tôi hiểu. Tôi sẽ chỉ làm CW này sau đó để lại lời phê bình. Có lẽ bạn nên đăng thông báo lỗi thực sự, tôi không thấy bất kỳ điều gì sai với mã của bạn. – GManNickG

3

Nó có vẻ là một vấn đề với định nghĩa của std :: hàm mẫu tối đa với các phiên bản của gcc < 4.4

Với gcc-4.4.0 và msvc Express9 nó hoạt động.

Các tác phẩm sau đây cũng cho gcc-3.4 và 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 
} 
Các vấn đề liên quan