【发布时间】:2014-04-23 22:52:42
【问题描述】:
是的,我知道,有一个标题几乎相同的问题,但它指的是不同的情况(给出相同的 clang 错误消息)。就我而言,我有一个 .cpp 文件,其中包含一个很大的匿名命名空间(包含实现细节)。在该命名空间中是一个带有静态数据成员的特征类模板,我需要从匿名命名空间外部访问它。让我稍微充实一下:
file.hpp
namespace bar {
template<typename A>
struct foo
{
static_assert(is_same<A,float>::value || is_same<A,double>::value, "");
static void set_static_var(A const&x);
// ...
};
}
和
file.cpp
namespace {
template<typename A>
struct foo_traits
{
// lots of static code supporting the implementation of bar::foo<>
static A datum;
};
template<> float foo_traits<float>::datum; // no change if this is in global namespace
template<> double foo_traits<double>::datum;
template struct foo_traits<float>;
template struct foo_traits<double>;
}
namespace bar {
template<typename A>
void foo<A>::set_static_var(A const&x)
{
foo_traits<A>::datum = x;
}
template struct foo<double>; // error only appears if these lines are present.
template struct foo<float>; // but without these lines, the whole file is void.
}
我在变量foo_traits<>::datum 上得到了上述错误(以及后来的链接失败)。 在编辑中添加注释我使用clang++ -std=c++11 -stdlib=libc++(3.3 版),它只产生一个警告,但(正如我所说)在我的实际应用程序中支持警告链接失败(正是缺少上述符号)。不过,gcc 没有编译器警告。也许这是一个clang错误? 结束说明
定义这些变量的正确方法是什么?请注意,在 anonymouns 命名空间之外声明它们不会编译。另请注意,AFAIK,具有普通非模板的相同构造也可以工作。
注意我不是在问如何规避这个问题(我自己能想到),而是如何正确地完成。
【问题讨论】:
-
@Casey 抱歉,我忘记了最重要的几行,即
file.cpp中的模板实例化。仅当添加这些错误时才会暴露该错误。所以,程序毕竟不正确。 -
@Casey 没有警告的编译并不意味着正确。我只收到一个警告(
clang++v3.3,gccv4.9 没有警告),但(在我的实际应用程序中)随后的链接失败。
标签: c++ templates namespaces linkage