I have such test.hpp:
#include <cstring>
#include <cassert>
#include <map>
template <typename T, typename Tag>
struct Boo {
  using ElementType = T;
  static const char name[];
};
struct CFG_ELM_NAME__Pref1 {};
using Pref1 = Boo<int, CFG_ELM_NAME__Pref1>;
struct Foo {
  template <typename CfgElm>
  void get() const {
    auto it = cache_.find(CfgElm::name);
    assert(it != cache_.end());
  }
  Foo();
private:
  struct CmpCStr final {
    bool operator()(const char *a, const char *b) const {
      return std::strcmp(a, b) < 0;
    }
  };
  using PrefCacheMap = std::map<const char *, int, CmpCStr>;
  PrefCacheMap cache_;
};
and use it like this (test2.cpp):
#include "test.hpp"
void f()
{
    Foo foo;
    foo.get<Pref1>();
}
and initialize it like this (test.cpp):
#include "test.hpp"
template <> const char Pref1::name[] = "Pref1";
Foo::Foo()
{
    cache_.insert(std::make_pair(Pref1::name, 17));
}
This is reduced example, so Foo::get do nothing.
clang produces such warning for this code:
clang++ -Wall -Wextra -std=c++11 test.cpp test2.cpp
In file included from test2.cpp:1:
./test.hpp:15:35: warning: instantiation of variable 'Boo<int,
      CFG_ELM_NAME__Pref1>::name' required here, but no definition is
      available [-Wundefined-var-template]
    auto it = cache_.find(CfgElm::name);
                                  ^
test2.cpp:6:6: note: in instantiation of function template specialization
      'Foo::get<Boo<int, CFG_ELM_NAME__Pref1> >' requested here
        foo.get<Pref1>();
            ^
./test.hpp:7:21: note: forward declaration of template entity is here
  static const char name[];
                    ^
./test.hpp:15:35: note: add an explicit instantiation declaration to
      suppress this warning if 'Boo<int, CFG_ELM_NAME__Pref1>::name' is
      explicitly instantiated in another translation unit
    auto it = cache_.find(CfgElm::name);
This codes does compiles and links without problems. The only problem is warning. I have no idea how to suppress it.
I found this question explicit instantiation of static variable of a template class in different translation units , but I can not use provided solution, because of I don't know template arguments.
I can not write: template<> int Boo<Type1, Type2>::name;
because of the whole idea is to use my code like this: foo.get<Pref1>(), without explicitly pointing that Pref1 is  Boo<int, CFG_ELM_NAME__Pref1>.
So anybody know how to suppress warning, without turn of such warning for whole project via -Wno-undefined-var-template?
 
     
    