2

Searching for duplicates currently gives:

  • This post which specifically treats the case of a Singleton implementation, and in which the answers avoids the warning altogether with a different implementation.
  • This post which answers itself without solving the issue.
  • A suggested duplicate which explains how to implement template member functions (not relevant).
  • Another suggested duplicate explaining how to define template static members (not relevant).

As far as I understand, none of these answers the question of how to get rid of Wundefined-var-template with clang++ 3.8+ in a situation similar to the MCVE below?


File a.h

#ifndef A_INCLUDED
#define A_INCLUDED

    template <class T>
    struct A
    {
        static const char *name;
    };

#endif

File a.cpp

#include "a.h"

template <> const char* A<double>::name = "Johnny";
template <> const char* A<float>::name = "Dude";

File b.cpp

#include <cstdio>
#include "a.h"

void say_it() {
    printf( "%s\n", A<double>::name );
}

Run from a terminal:

$ clang++ -c -o a.o -std=c++11 a.cpp
$ clang++ -c -o b.o -std=c++11 b.cpp a.o
clang: warning: a.o: 'linker' input unused [-Wunused-command-line-argument]
b.cpp:5:32: warning: instantiation of variable 'A<double>::name' required here, but no definition is available [-Wundefined-var-template]
    printf( "%s\n", A<double>::name );
                               ^
./a.h:7:28: note: forward declaration of template entity is here
        static const char *name;
                           ^
b.cpp:5:32: note: add an explicit instantiation declaration to suppress this warning if 'A<double>::name' is explicitly instantiated in another translation unit
    printf( "%s\n", A<double>::name );
                               ^
1 warning generated.

Demo

Jarod42
  • 203,559
  • 14
  • 181
  • 302
Jonathan H
  • 7,591
  • 5
  • 47
  • 80

1 Answers1

2

Do as warning message explain, add (in a.h):

template <> const char* A<double>::name;

Demo

Jarod42
  • 203,559
  • 14
  • 181
  • 302
  • Will accept when SO lets me; it wasn't clear to me what "explicit instantiation declaration" meant, or where it should be inserted. See also [this post](https://stackoverflow.com/q/25056802/472610). – Jonathan H Jun 05 '19 at 15:03
  • Are you sure that's a declaration and not a definition? – Quentin Jun 05 '19 at 15:05
  • @Quentin That's precisely what [this post](https://stackoverflow.com/q/25056802/472610) is about. I'm hesitating to close my question as a duplicate.. – Jonathan H Jun 05 '19 at 15:07
  • This is a declaration. C++17 says in [17.7.3.13]: "An explicit specialization of a static data member of a template or an explicit specialization of a static data member template is a definition if the declaration includes an initializer; otherwise, it is a declaration." – RichyBK Feb 08 '21 at 11:24