2014-02-19 80 views
-1
#include<iostream> 
#include "stdlib.h" 

using namespace std; 

#include<vector> 
#include<iterator> 

template <typename type1> 
vector<type1> map(vector<type1> &my_vec, type1 (*my_fun)(type1)){ 
    vector<type1> result_vec; 
    for(vector<type1>::iterator iter = my_vec.begin(); iter != my_vec.end() ; iter++){ 
     result_vec.push_back(my_fun(*iter)); 
    } 
    return result_vec; 
} 

在這個節目,我想編寫一個地圖功能(類似於一個在python),但也有一些是錯誤的錯誤,編譯器會告訴我:關於C++泛型編程

In function 'std::vector<type1> map(std::vector<type1>&, type1 (*)(type1))': 
[Error] need 'typename' before 'std::vector<type1>::iterator' because 'std::vector<type1>' is a dependent scope 
[Error] expected ';' before 'iter' 
[Error] 'iter' was not declared in this scope 

什麼問題是什麼? (當我將「type1」更改爲「int」時,一切正常)

+2

如果你打算使用已經存在於標準庫中的名字(比如'map'),你可能不應該使用'namespace std'。事實上,'使用名稱空間std'通常是一個糟糕的主意。 –

+0

您是否要求人們爲您讀取編譯器錯誤?它正在告訴你,你需要做什麼來解決這個問題,它會給你一個很好的,可搜索的,暗示問題的原因。 – juanchopanza

回答

4

錯誤消息很直接地告訴你你需要做什麼。變化:

for(vector<type1>::iterator iter = my_vec.begin(); iter != my_vec.end() ; iter++){ 

...到:

for(typename vector<type1>::iterator iter = my_vec.begin(); iter != my_vec.end(); iter++){ 

的電流(C++ 11)編譯器,你可能會更好重寫,以避免(明確的)迭代器完全使用:

for (auto const & i : my_vec) 
    result_vec.push_back(my_fun(i)); 

雖然這些只是解決了短期的語法問題。有幾個更大的問題。首先,map已經在標準庫中(具有完全不同的含義),所以最好避免使用該名稱。

的還是更大的問題是,這整個事情非常簡單,只是的(的一元版)std::transform贗品,而你通常會更好,只是用std::transform不是試圖編寫自己的。

至於爲什麼它與int,而不是vector<type1>::iterator作品隱含的問題:這是相當簡單的真:編譯器總是「知道」 int(作爲一個完整的令牌)是一種類型。它不能用於其他任何事情。

在模板中,編譯器「知道」像T::foo名(其中T是一個模板參數)是否是一種或類似的成員變量名的名稱。爲了消除歧義,您可以明確指定typename。在你的情況下,表達式並不像T::foo那麼簡單,但它仍然依賴於模板參數。