2011-10-19 81 views
0

假設您想對容器對象的元素進行迭代修改,並在每次迭代時對元素執行一些操作。我想出了代碼做這樣的事情:傳遞函數對象時發生編譯錯誤

#include <vector> 
#include <iostream> 

template <class InputIterator, class Operation, class Callback> 
void transformAndTraverse(InputIterator begin, InputIterator end, Operation op, Callback cb) { 
    InputIterator start = begin; 
    while (begin != end) { 
    op(begin); 
    cb(start, end); 
    ++begin; 
    } 
} 

template <class InputIterator> 
struct plotFnObject { 
    void operator()(InputIterator begin, InputIterator end) { 
    while (begin < end) { 
     std::cout << *begin << " "; 
     ++begin; 
    } 
    std::cout << std::endl; 
    } 
}; 

template <class InputIterator> 
struct addTwoFnObject { 
    void operator()(InputIterator idata) { *idata += 2; } 
}; 

int main(int argc, char **argv) { 
    typedef std::vector<int>::iterator vec_iter; 
    std::vector<int> vec; 
    vec.push_back(0); 
    vec.push_back(0); 
    vec.push_back(0); 

#ifndef DEMO_COMPILE_ERROR 
    // the below works 
    transformAndTraverse(vec.begin(), vec.end(), addTwoFnObject<vec_iter>(), plotFnObject<vec_iter>()); 
#else 
    // but this generates compilation errors 
    addTwoFnObject<vec_iter> addtwo(); 
    plotFnObject<vec_iter> plot(); 
    transformAndTraverse(vec.begin(), vec.end(), addtwo, plot); 
#endif 
} 

麻煩的是,我得到一些很難理解與第二種形式編譯器錯誤:

$ g++ testtemplate.cpp -DDEMO_COMPILE_ERROR 
testtemplate.cpp: In function 'void transformAndTraverse(InputIterator, InputIterator, Operation, Callback) [with InputIterator = __gnu_cxx::__normal_iterator<int*, std::vector<int> >, Operation = addTwoFnObject<__gnu_cxx::__normal_iterator<int*, std::vector<int> > > (*)(), Callback = plotFnObject<__gnu_cxx::__normal_iterator<int*, std::vector<int> > > (*)()]': 
testtemplate.cpp:44:60: instantiated from here 
testtemplate.cpp:8:5: error: too many arguments to function 
testtemplate.cpp:9:5: error: too many arguments to function 

$ g++ testtemplate.cpp 
$ 

爲什麼編譯器創建OK該函數對象內聯,但不是創建它們並且傳遞它們?

$ g++ --version 
g++ (GCC) 4.5.3 
Copyright (C) 2010 Free Software Foundation, Inc. 
This is free software; see the source for copying conditions. There is NO 
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 

回答

4

這些是函數的聲明:

addTwoFnObject<vec_iter> addtwo(); 
plotFnObject<vec_iter> plot(); 

這些是局部變量實例:

addTwoFnObject<vec_iter> addtwo; 
plotFnObject<vec_iter> plot; 

您需要在最後失去了額外的括號,否則編譯器會抱怨這裏您正試圖在不提供參數列表的情況下調用假設函數addtwo

transformAndTraverse(vec.begin(), vec.end(), addtwo, plot); 
+0

啊,現在有道理。 – veefu

2
addTwoFnObject<vec_iter> addtwo(); 
plotFnObject<vec_iter> plot(); 

聲明瞭一個名爲addtwoplot,分別返回addTwoFnObject<vec_iter>plotFnObject<vec_iter>功能。去除 ()。

谷歌對於「最令人頭痛的解析」瞭解更多信息。

相關問題