2013-07-22 65 views
0

內部inner_product以下代碼:編譯錯誤到另一個功能

$ cat test02.cpp 
#include <string> 
#include <numeric> 
#include <cstdlib> 
#include <list> 
#include <iostream> 

struct myadd : 
    public std::binary_function 
     <const std::string&,const std::string&,std::string> 
{ 
    std::string operator() (const std::string& x,const std::string& y) const { 
     return x+" "+y; 
    } 
}; 

struct mymul : 
    public std::binary_function 
     <const std::string&,const std::string&,std::string> 
{ 
    std::string operator() (const std::string& x,const std::string& y) const { 
     return x+y; 
    } 
}; 

std::string spliceme(
    const std::list <std::string>& list1, 
    const std::list <std::string>& list2, 
    const std::binary_function 
     <const std::string&,const std::string&,std::string>& add, 
    const std::binary_function 
     <const std::string&,const std::string&,std::string>& mul 
) { 
    return std::inner_product(list1.cbegin(),list1.cend(),list2.cbegin(), 
     std::string(""),add,mul); 
} 

int main() { 
    std::list <std::string> list1; 
     list1.emplace_back("First"); 
     list1.emplace_back("Second"); 
     list1.emplace_back("Third"); 
    std::list <std::string> list2; 
     list2.emplace_back("Foerst"); 
     list2.emplace_back("Annen"); 
     list2.emplace_back("Tredje"); 

    std::string result = spliceme(list1,list2,myadd(),mymul()); 
    std::cout << result << std::endl; 

    return EXIT_SUCCESS; 
} 

生成編譯器錯誤:

g++ -std=c++0x test02.cpp -o test02 
In file included from /usr/lib/gcc/i686-pc-linux-gnu/4.6.3/include/g++-v4/numeric:62:0, 
       from test02.cpp:2: 
/usr/lib/gcc/i686-pc-linux-gnu/4.6.3/include/g++-v4/bits/stl_numeric.h: In function '_Tp std::inner_product(_InputIterator1, _InputIterator1, _InputIterator2, _Tp, _BinaryOperation1, _BinaryOperation2) [with _InputIterator1 = std::_List_const_iterator<std::basic_string<char> >, _InputIterator2 = std::_List_const_iterator<std::basic_string<char> >, _Tp = std::basic_string<char>, _BinaryOperation1 = myadd, _BinaryOperation2 = std::binary_function<const std::basic_string<char>&, const std::basic_string<char>&, std::basic_string<char> >]': 
test02.cpp:29:101: instantiated from here 
/usr/lib/gcc/i686-pc-linux-gnu/4.6.3/include/g++-v4/bits/stl_numeric.h:218:2: error: no match for call to '(std::binary_function<const std::basic_string<char>&, const std::basic_string<char>&, std::basic_string<char> >) (const std::basic_string<char>&, const std::basic_string<char>&)' 
make: *** [all] Error 1 

在線路中發生的問題:

return std::inner_product(list1.cbegin(),list1.cend(),list2.cbegin(), 
    std::string(""),add,mul); 

如果我直接實例化類myadd和mymul:

return std::inner_product(list1.cbegin(),list1.cend(),list2.cbegin(), 
    std::string(""),myadd(),mymul()); 

所有內容都編譯並正確運行。我在傳遞函數add和mul到函數spliceme中的方式有​​什麼問題?

回答

3

無論這樣的:

std::string spliceme(
    const std::list <std::string>& list1, 
    const std::list <std::string>& list2, 
    const std::function<std::string(const std::string&,const std::string&)>& add, 
    const std::function<std::string(const std::string&,const std::string&)>& mul 
) { 
    return std::inner_product(list1.cbegin(),list1.cend(),list2.cbegin(), 
    std::string(""),add,mul); 
} 

或該:

template<typename Add, typename Mul> 
std::string spliceme(
    const std::list <std::string>& list1, 
    const std::list <std::string>& list2, 
    const Add& add, 
    const Mul& mul 
) { 
    return std::inner_product(list1.cbegin(),list1.cend(),list2.cbegin(), 
    std::string(""),add,mul); 
} 

使您的代碼正常工作。第一種使用類型擦除功能,第二種使用template函子。第一個可以讓你將身體分離出頭部,第二個可以改善輪廓。

2
std::string spliceme(
    const std::list <std::string>& list1, 
    const std::list <std::string>& list2, 
    const std::binary_function 
     <const std::string&,const std::string&,std::string>& add, 
    const std::binary_function 
     <const std::string&,const std::string&,std::string>& mul 
) 

應該是:

std::string spliceme(
    const std::list <std::string>& list1, 
    const std::list <std::string>& list2, 
    const myadd& add, 
    const mymul& mul 
) { 

因爲操作者()不是虛函數

+0

我希望能夠通過任意的二進制函數,而不僅僅是myadd和mymul。 – wyer33

1

std::binary_function是一個便捷的模板,用於向函數對象中添加三個typedef。它從來沒有打算被用作函數簽名中的基類,因爲發生的所有事情都是你的對象被切片。它在C++ 11中已被棄用,不應再使用。 Yakk對你應該做的事情給出了很好的答案。如果您確實需要這些typedef(first_argument_type,second_argument_typeresult_type),請自行添加它們。

相關問題