C++11 “固定警告”;Wundefined var模板“;

C++11 “固定警告”;Wundefined var模板“;,c++11,compiler-warnings,clang++,C++11,Compiler Warnings,Clang++,搜索当前的重复项将提供: 它专门处理单例实现的情况,其中的答案使用不同的实现完全避免了警告 而不是解决问题 解释如何实现模板成员函数(不相关)的 另一个例子解释了如何定义模板静态成员(不相关) 据我所知,这些都不能回答在与下面的MCVE类似的情况下,如何使用clang++3.8+摆脱Wundefined var模板的问题? 文件a.h #ifndef A_INCLUDED #define A_INCLUDED template <class T> struct

搜索当前的重复项将提供:

  • 它专门处理单例实现的情况,其中的答案使用不同的实现完全避免了警告
  • 而不是解决问题
  • 解释如何实现模板成员函数(不相关)的
  • 另一个例子解释了如何定义模板静态成员(不相关)
据我所知,这些都不能回答在与下面的MCVE类似的情况下,如何使用clang++3.8+摆脱
Wundefined var模板的问题?


文件
a.h

#ifndef A_INCLUDED
#define A_INCLUDED

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

#endif
文件
b.cpp

#include "a.h"

template <> const char* A<double>::name = "Johnny";
template <> const char* A<float>::name = "Dude";
#include <cstdio>
#include "a.h"

void say_it() {
    printf( "%s\n", A<double>::name );
}
#包括
#包括“a.h”
空说{
printf(“%s\n”,A::name);
}
从终端运行:

$ 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.
$clang++-c-o a.o-std=c++11 a.cpp
$clang++-c-ob.o-std=c++11b.cpp a.o
叮当声:警告:a.o:“链接器”输入未使用[-Wunused命令行参数]
b、 cpp:5:32:警告:此处需要实例化变量“A::name”,但没有可用的定义[-Wundefined var template]
printf(“%s\n”,A::name);
^
./a.h:7:28:注:此处为模板实体的转发声明
静态常量字符*名称;
^
b、 cpp:5:32:注意:如果在另一个翻译单元中显式实例化了“A::name”,则添加显式实例化声明以抑制此警告
printf(“%s\n”,A::name);
^
生成1个警告。

按照警告消息的说明,添加(在a.h中):

template const char*A::name;

IIRC这只是
extern-template-const-char*A::name等。可能重复:将在允许时接受;我不清楚“显式实例化声明”是什么意思,或者应该插入到哪里。另见。你确定这是一个声明而不是一个定义吗?@Quentin这正是问题所在。我在犹豫是否把我的问题作为一个重复来结束这是一个声明。C++17在[17.7.3.13]中说:“如果声明包含初始值设定项,则模板静态数据成员的显式专门化或静态数据成员模板的显式专门化是一个定义;否则,它是一个声明。”
template <> const char* A<double>::name;