0

How can achieve external linkage for class static functions when the compiler thinks the code is local linkage or inline?

Consider three files:

traits.h:

template <typename T>
struct Traits
{
    static int InlineFunction(T);
    static int Function(T);
};

traitsimp.cpp:

#include "traits.h"
template <>
struct Traits<int>
{
    static int InlineFunction(int) { return 42; }
    static int Function(int);
};

int Traits<int>::Function(int i) { return i; }

main.cpp:

#include "traits.h"
int main()
{
    int result = Traits<int>::Function(5);
    result = Traits<int>::InlineFunction(result);
    return 0;
}

When compiled receives:

$ g++ traitsimp.cpp main.cpp -o traitstest
/tmp/cc6taAop.o: In function `main':
main.cpp:(.text+0x1b): undefined reference to `Traits<int>::InlineFunction(int)'
collect2: ld returned 1 exit status

How do I convince the compiler to give InlineFunction external linkage while still writing the function within the class definition?

Bill Door
  • 18,272
  • 3
  • 32
  • 37
  • Isn't that exactly what you did with `Function`? – Keith Mar 13 '13 at 04:30
  • Updated. I'd like to not be forced to write the functions outside of the class definition. And even more importantly, why does it matter? – Bill Door Mar 13 '13 at 04:32
  • afaik, it does not matter if you write within the class or externally like the implementation file. – Aniket Inge Mar 13 '13 at 04:34
  • See also: http://stackoverflow.com/questions/4446968/template-specialization-multiply-defined-symbols/4447405#4447405 – Keith Mar 13 '13 at 04:35

1 Answers1

0

I think you need to decide whether to have external linkage and define out of line or keep it inline and effectively just have internal linkage. Is there a reason not to define your Traits<int> in a header? Note that the full specialization is no longer a template, so there is really no difference to how it is handled versus a non-templated function.

Edited: Tried this in VS2010, and it may still not suit, but you could put code in traitsimp.cpp that takes the address of the method:

auto getAddress = &Traits<int>::InlineFunction;

This forces the method to get an address. I'm a bit rusty on whether this behaviour would be standard or not.

Keith
  • 6,756
  • 19
  • 23