7

I am trying to use a local class as a functor and get compiler error using g++ (3.4.6).

Placing the below class ( Processor ) in the global scope resolves the error, so I guess the error is because of function local structures/classes. I would prefer to have the classes inside the function for code clarity and ease of use. Want to know if there is a workaround solution to make the below code working.

test.cpp:24: error: no matching function for call to \u2018foreachArg(int&, char*&, processSubs(int, char*)::Processor&)\u2019

template <class Functor>
void foreachArg(int n, char *args[], Functor& f)
{
    for(int i=0; i<n; ++i)
        f(args[i]);
}

int processSubs(int argc, char *args[])
{
    class Processor
    {
        public:
            void operator()(const char *arg)
            {
            }
    };

    Processor p;
    foreachArg(argc, args, p);
}

int main(int argc, char *argv[])
{
    processSubs(argc, argv);
}
Bo Persson
  • 90,663
  • 31
  • 146
  • 203
Shanky
  • 139
  • 1
  • 12
  • No, the two options are using a C++11 compatible compiler, or move the class outside the function. – Bo Persson Mar 19 '12 at 15:10
  • Please see: http://stackoverflow.com/a/2598272/294864 for a reference to before-C++11-specification regarding anonymous structs as template argments. – Akanksh Mar 19 '12 at 15:51
  • There's a third option - use a “local” functor idiom. Boost is adding one, for example. – Luis Machuca Aug 09 '12 at 16:32

4 Answers4

9

In C++, prior to C++11, classes used as arguments to template functions must have external linkage. Local classes don't have external linkage so you can't use them this way.

C++11 changes this, so you may be able to fix this by setting your compiler to use C++11.

bames53
  • 86,085
  • 15
  • 179
  • 244
  • unfortunately using a compiler (3.4.6 --- stuck in stone age :P ) which doesn't support c++0x so looking for smart workaround – Shanky Mar 19 '12 at 15:05
  • There's not really a workaround. Some compilers have an extension to allow this pre-C++11, but not gcc as far as I know. If you're stuck with your current compiler I don't think there's a better option than moving the functor out of the local scope. @Shanky – bames53 Mar 19 '12 at 15:10
  • There's actually some workarounds. Not sure if it works in GCC 3.x, but in GCC 4.2 and 4.4 I'm using a very simple `LOCAL_FUNCTION` idiom, based on inheritance and template specialization, that delegates the actual function call to external, base functors that virtually forward to the local ones. Boost seems to have recently launched something like that (and as usual with Boost, much better but at a tremendous complexity and dependency cost). – Luis Machuca Aug 09 '12 at 03:00
0

You cannot instantiate templates with local classes in C++03.

Also, the Standard already provides a function for this- std::for_each.

Puppy
  • 144,682
  • 38
  • 256
  • 465
0

C++03 doesn't allow locally defined classes to be template arguments, as you've found out here. C++11 allows this. With gcc, you might try compiling with --std=c++0x

Managu
  • 8,849
  • 2
  • 30
  • 36
  • unfortunately using a compiler (3.4.6 --- stuck in stone age :P ) which doesn't support c++0x so looking for smart workaround – Shanky Mar 19 '12 at 15:04
0

As has been said, using local classes for this was not possible pre-C++11, and about useless in C++11 because lambdas are less wordy.

You should simply declare your class outside the function.

Matthieu M.
  • 287,565
  • 48
  • 449
  • 722