C++ 模板类字段的显式实例化声明
我有这样的C++ 模板类字段的显式实例化声明,c++,c++11,templates,clang++,C++,C++11,Templates,Clang++,我有这样的测试.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<i
测试.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_;
};
#include "test.hpp"
void f()
{
Foo foo;
foo.get<Pref1>();
}
#include "test.hpp"
template <> const char Pref1::name[] = "Pref1";
Foo::Foo()
{
cache_.insert(std::make_pair(Pref1::name, 17));
}
然后像这样初始化它(test.cpp
):
这段代码编译和链接没有问题。
唯一的问题是警告。
我不知道如何抑制它
我发现了这个问题,但我不能使用提供的解决方案,因为我不知道模板参数
我不会写:template int Boo::name代码>
因为整个想法是这样使用我的代码:foo.get()
,而不明确指出Pref1
是Boo
因此,任何人都知道如何通过-Wno undefined var template
?抑制警告,而不必通过-Wno undefined var template对整个项目发出警告,您应该在同一头文件中添加Boo::name
模板定义:
static const char * name;
}; // End Boo
template<typename T, typename Tag>
const char * Boo<T, Tag>::name{};
它可以工作,但我必须删除*
并添加[]{}
,使其编译时不会出错。但在最后,初始化意味着什么呢?但是我在other.cpp
中的initname
没有显示在我的问题中。@user1244932{}
末尾是一个。在.cpp
中初始化name
不是一个好主意,请参阅。我不会在cpp中初始化整个模板,而是初始化具体类型,如下所示template const char Pref1::name[]=“Pref1”代码>我已经更新了我的问题,以显示我如何初始化name
。我尝试了您的解决方案,它可以在链接时间内使用clang++
,但是g++-Wall-Wextra-std=c++11 test.cpp test2.cpp
返回名称的多个定义
,但是在没有模板const char*Boo::name{}的情况下编译得很好代码>我使用了clang 5.0.1和gcc 7.2.1。
static const char * name;
}; // End Boo
template<typename T, typename Tag>
const char * Boo<T, Tag>::name{};
// header
template <typename T, typename Tag> struct Boo {
using ElementType = T;
static const char * name;
};
struct CFG_ELM_NAME__Pref1 {};
// indicate that name for this specialization exists elsewhere
template<> const char * Boo<int, CFG_ELM_NAME__Pref1>::name;
// indicate that template is defined somewhere
extern template struct Boo<int, CFG_ELM_NAME__Pref1>;
using Pref1 = Boo<int, CFG_ELM_NAME__Pref1>;
// test.cpp
// definition will be present only in this translation unit
template<> const char * Boo<int, CFG_ELM_NAME__Pref1>::name{"Pref1"};
// explicit instantiation
template struct Boo<int, CFG_ELM_NAME__Pref1>;