0

The sample code compiles without warning or error on Windows and Linux. It starts to get the -Wundefined-var-template warning in XCode 9.

foo.h:

template <typename T>
struct myClass
{
    static const char* name;
};

foo.cpp:

#include "foo.h"
template<>
const char *myClass<int>::name = "int";

warning: instantiation of variable 'myClass<int>::name' required here, but no definition is available [-Wundefined-var-template] 

note: forward declaration of template entity is here 
    static const char *name; 
                       ^ 
note: add an explicit instantiation declaration to suppress this warning if 'myClass<int>::name' is explicitly instantiated in another translation unit
Chnossos
  • 9,971
  • 4
  • 28
  • 40
Batistuta
  • 127
  • 1
  • 9
  • Possible duplicate of [Why can templates only be implemented in the header file?](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – 463035818_is_not_an_ai Nov 10 '17 at 20:13
  • It is not a duplicate, because static variables cannot be inlined, so they cannot be handled in the same way as functions. Please see "What I tried but didn't work" section in my own answer. – Batistuta Nov 11 '17 at 03:19
  • they can when they are template members. Here is a better dupe: https://stackoverflow.com/questions/3229883/static-member-initialization-in-a-class-template – 463035818_is_not_an_ai Nov 11 '17 at 10:47
  • ...hm actually now I not sure anymore, because `myClass` is a concrete type, not a template anymore. – 463035818_is_not_an_ai Nov 11 '17 at 10:49
  • Thanks for looking into it, tobi303. I tried the solution https://stackoverflow.com/questions/3229883/static-member-initialization-in-a-class-template, as mentioned in the second bullet in "What I tried but didn't work". – Batistuta Nov 13 '17 at 01:42

1 Answers1

0

What I tried but didn't work:

  • Moving the code in foo.cpp to foo.h resulted in "duplicate code" error at link-time, because foo.h was included by multiple files.
  • Adding the following code in the header file can resolve the warning, but the code fails at runtime.

    template<T>
    const char *myClass<T>::name = "";
    

What worked in the end:

foo.h:

template <typename T>
struct myClass
{
    static const char* name;
};

template <>
struct myClass<int>
{
    static const char* name;
};

foo.cpp:

#include "foo.h"
const char *myClass<int>::name = "int";
Batistuta
  • 127
  • 1
  • 9
  • 1
    how does this solve the problem? You've simply defined a specialization of the entire template, which defies the point of the template – jwm Jul 30 '18 at 07:03