传递函数对象时出现编译器错误

Compiler error while passing function objects

本文关键字:编译器 错误 对象 传递函数      更新时间:2023-10-16

假设您希望对容器对象的元素进行迭代修改,并在每次迭代时对元素进行处理。我想出的代码是这样做的:

#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
$

为什么编译器可以在线创建函数对象,而不能离线创建并传递它们?

$ 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.

这些是函数的声明:

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

这些是局部变量实例化:

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

您需要在末尾丢失多余的parens,否则编译器会抱怨您试图在没有提供参数列表的情况下调用假设函数addtwo

transformAndTraverse(vec.begin(), vec.end(), addtwo, plot);
addTwoFnObject<vec_iter> addtwo();
plotFnObject<vec_iter> plot();

声明了名为addtwoplot的函数,分别返回addTwoFnObject<vec_iter>plotFnObject<vec_iter>。卸下((。

谷歌搜索"最令人烦恼的解析"以获取更多信息。