2012-08-17 180 views
0

我想在第5.9章結束時做11個練習Bjarne Stroustrup C++編程語言。C++編譯錯誤(gcc 4.7)

1 #include <iostream> 
    2 #include <string> 
    3 #include <vector> 
    4 #include <algorithm> 
    5 
    6 void print(std::vector<std::string>::const_iterator str) { 
    7 std::cout << *str; 
    8 } 
    9 
10 int main(void) { 
11 std::vector<std::string> words; 
12 std::string tmp; 
13 
14 std::cin >> tmp; 
15 while (tmp != "Quit") { 
16  words.push_back(tmp); 
17  std::cin >> tmp; 
18 } 
19 
20 for_each(words.begin(), words.end(), print); 
21 
22 return 0; 
23 } 

當我去掉20行我得到這個錯誤:

In file included from /usr/include/c++/4.7/algorithm:63:0, 
       from 5.9.11.cpp:4: 
/usr/include/c++/4.7/bits/stl_algo.h: In instantiation of ‘_Funct std::for_each(_IIter, _IIter, _Funct) [with _IIter = __gnu_cxx::__normal_iterator<std::basic_string<char>*, std::vector<std::basic_string<char> > >; _Funct = void (*)(__gnu_cxx::__normal_iterator<const std::basic_string<char>*, std::vector<std::basic_string<char> > >)]’: 
5.9.11.cpp:20:44: required from here 
/usr/include/c++/4.7/bits/stl_algo.h:4442:2: error: could not convert ‘__first.__gnu_cxx::__normal_iterator<_Iterator, _Container>::operator*<std::basic_string<char>*, std::vector<std::basic_string<char> > >()’ from ‘std::basic_string<char>’ to ‘__gnu_cxx::__normal_iterator<const std::basic_string<char>*, std::vector<std::basic_string<char> > >’ 

編譯命令:

g++ prog.cpp -o prog -Wall 

我做錯了什麼?

回答

2

回調函數應該採用std::string,而不是迭代器。 for_each傳遞每個元素本身。因此,你的函數將成爲:

void print(const std::sting &str) { 
    std::cout << str << ' '; //note I separated the words 
} 

對於一個固定的例子(包括std::for_each,還有幾個其他的細微差別),看到this run

在C++ 11(可訪問到你的編譯器通過-std=c++0x-std=c++11),你甚至不需要通過容器擔心std::for_each循環,因爲C++ 11引入了遠程-for循環:

for (const std::string &str : words) 
    std::cout << str << ' '; 
+0

+1對於基於範圍的項目,並沒有多花時間用在VC2010(它不支持它)上。 – hmjd 2012-08-17 16:22:43

+0

@hmjd,是的,我發現C++ 11最有用的功能之一,並且聽說它不支持那裏:/ – chris 2012-08-17 16:24:06

1

正如chris所述,print()函數應接受const std::string&。作爲替代方案,你可以使用lambda函數:

std::for_each(words.begin(), 
       words.end(), 
       [](const std::string& a_s) 
       { 
        std::cout << a_s << "\n"; 
       }); 

添加編譯器標誌-std=c++0x

+0

好的建議,但如果我們進入C++ 11,範圍因爲這將是我的首選。我想我會將該選項添加到列表中。 – chris 2012-08-17 16:16:38

+0

@chris,g ++ v4.7支持一些C++ 11特性,爲什麼不呢? – hmjd 2012-08-17 16:17:20

+0

好點。我沒有注意到編譯器版本。 – chris 2012-08-17 16:18:42