veefu
veefu

Reputation: 2890

Compiler error while passing function objects

Say you would like to make iterative modifications to the elements of a container object and do something with the elements at each iteration. The code I came up with to do something like this:

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

The trouble is that I get some difficult to understand compiler errors with the second form:

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

Why is the compiler OK with creating the function objects in-line, but not with creating them out of line and passing them?

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

Upvotes: 0

Views: 132

Answers (2)

PlasmaHH
PlasmaHH

Reputation: 16046

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

declares functions named addtwo and plot, returning addTwoFnObject<vec_iter> and plotFnObject<vec_iter> respectively. Remove the ().

Google for "most vexing parse" for further information.

Upvotes: 2

Jon
Jon

Reputation: 437336

These are declarations of functions:

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

These are local variable instantiations:

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

You need to lose the extra parens at the end, otherwise the compiler complains that here you are trying to call the hypothetical function addtwo without providing an argument list:

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

Upvotes: 4

Related Questions