For various reasons, I want to make a functor that is a static member of another class. However, this SOMETIMES causes a linker error. Is this not legal? If so, why not?
Here's a minimal example.
#include <iostream>
struct {
int operator() (int x) {return x*x;}
} standaloneFunctor;
struct Thing {
struct { int operator() (int x) {return x*x;} } memberFunctor;
static struct { int operator() (int x) {return x*x;} } staticFunctor;
};
int main () {
std::cout << standaloneFunctor(3) << '\n'; // call the stand-alone functor
Thing thing;
std::cout << thing.memberFunctor(3) << '\n'; // call functor that is member of class
std::cout << Thing::staticFunctor(3) << '\n'; // call functor that is static member of class
return 0;
}
Compiling and linking with -O0 causes a linker error:
yloh$ g++ a.cc -O0 -o a ; ./a
/usr/bin/ld: /tmp/ccd6rdI7.o: in function `main':
a.cc:(.text+0x8e): undefined reference to `Thing::staticFunctor'
collect2: error: ld returned 1 exit status
bash: ./a: No such file or directory
Compiling and linking with -O3 leads to the expected result in this case (but fails for more sophisticated programs):
yloh$ g++ a.cc -O3 -o a ; ./a
9
9
9
The compiler version is g++ (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0. Can anyone explain what causes the linker error, and suggest a workaround? [Presumably one workaround is to define a dummy object and call the functor that is its data member, but that sounds hacky.] Thanks in advance!