【问题标题】:Non-trivially initializing static member of template class in C++11 without clang warnings在 C++11 中非平凡地初始化模板类的静态成员,而不会发出 clang 警告
【发布时间】:2018-09-07 16:26:56
【问题描述】:

我有一个模板类,其结构如下:

foobar.h:

class Bar
{
    Bar(float f);
};

template<typename T>
class Foo
{
    Foo(const Bar&);
    ...
    static const Foo mkFooConst;
};

typedef Foo<float> MathFoo;

foobar.c:

template<> const MathFoo MathFoo::mkFooConst(Bar(0.815));

现在这似乎是初始化模板类的静态成员的常用方法,该静态成员无法在其声明中简单地初始化。对于 VS 2015 和 g++,它似乎运行良好。

但是,clang 不同意,并在类最终使用时发出警告:

warning: instantiation of variable 'Foo<float>::mkFooConst' required
here, but no definition is available [-Wundefined-var-template]
...
note: add an explicit instantiation declaration to suppress this
warning if 'Foo<float>::mkFooConst' is explicitly instantiated in
another translation unit.

据我了解,这意味着我应该在头文件中添加以下代码:

extern template class MathFoo<float>;

大概是cpp文件的以下内容:

template class MathFoo<float>;

但无论我把它放在哪里,这一切都给我一个彻底的错误而不是警告 - '实例化后的显式特化'或 '实例化后的显式特化''特化后的显式实例化'。

我还尝试为成员添加显式实例化声明,但这也不起作用。

有什么想法吗?

不幸的是,C++17 对我来说不是一个选择;代码必须与 C++11 兼容。

【问题讨论】:

  • @Swordfish:在我看来,这根本不像是复制品。这里的 OP 正在使用该问题的技术解决方案之一。
  • 重新打开,因为希望的欺骗不是。
  • 除了float之外,您是否必须支持其他模板类型参数,可能有不同的值?因为如果不是,那么作为一种实际的解决方法,您可以在标题中提供一个模板化的一般定义。不过,这仍然留下了铿锵的问题。
  • 我无法重现该问题。请编辑您的问题并添加mcve
  • “‘实例化后的显式特化’或‘实例化后的显式特化’。”它们是一样的。也许你不小心把同一个贴了两次?

标签: c++ c++11 templates clang


【解决方案1】:

你必须输入:

template<> const MathFoo MathFoo::mkFooConst;
// Declaration only, mkFooConst{} would be a definition.

Demo with multiple file

No warning with clang

【讨论】:

  • 我没有机会测试这个答案(我以不同的方式解决它),但我想这是有道理的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-03-10
  • 1970-01-01
  • 2011-03-14
相关资源
最近更新 更多