c++ - header 中的模板规范问题

标签 c++ templates

我必须将一些代码从 Microsoft Visual Studio 编译器移植到 clang。这让我有些紧张。因为我必须确保代码仍然可以使用 MVSC 进行编译/链接。以下代码是corpus delicti。重要的是,我不能将代码拆分为 src 和头文件。

编译器:6.0.0-1ubuntu2 和 Visual Studio 2015

C++:版本 14

操作系统:Ubuntu 18.04 和 Windows 10/7

代码在头文件中。我将它包含在几个 src 文件中。

代码:

#ifndef GLOBAL_SETTINGS_
#define GLOBAL_SETTINGS_

#include <cstdint>

namespace global {
    enum resolution {
        Hz,
        kHz,
        MHz
    };

    template<resolution T>
    struct sys_clk
    {
        static const double frequency;
    };

#define SYS_CLK_FREQ (115.0e6)

    template<> const double sys_clk<Hz>::frequency = SYS_CLK_FREQ;
    template<> const double sys_clk<kHz>::frequency = SYS_CLK_FREQ/1.0e3;
    template<> const double sys_clk<MHz>::frequency = SYS_CLK_FREQ/1.0e6;

#undef SYS_CLK_FREQ

} // namespace global

#endif /* GLOBAL_SETTINGS_ */

这编译得很好,但链接器发现自己无法解决。

链接器错误:

multiple definition of `global::sys_clk_scon<(global::resolution)0>::frequency'
multiple definition of `global::sys_clk_scon<(global::resolution)1>::frequency'
multiple definition of `global::sys_clk_scon<(global::resolution)2>::frequency'

问题:

这个链接器错误是如何解决的,所以它可以在 MVSC 和 clang 中编译?

最佳答案

与其专门化静态变量,不如专门化整个类。这将允许您创建变量 constexpr,从而消除在任何 TU 中定义它们的需要。

    template<resolution T>
    struct sys_clk;

#define SYS_CLK_FREQ (115.0e6)

    template<> struct sys_clk<Hz> {
      static constexpr double frequency = SYS_CLK_FREQ;
    };
    template<> struct sys_clk<kHz> {
      static constexpr double frequency = SYS_CLK_FREQ/1.0e3;
    };
    template<> struct sys_clk<MHz> {
      static constexpr double frequency = SYS_CLK_FREQ/1.0e6;
    };

#undef SYS_CLK_FREQ

需要注意的是,您必须确保它们未被 ODR 使用(使用它们的地址或绑定(bind)引用)。因为那时你的多重定义错误将变成一个 Unresolved 定义错误。

关于c++ - header 中的模板规范问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57867155/

相关文章:

C++ - 如何在自定义模板化数据容器中的迭代器上使用 advance() 启用 ADL?

html - 什么是最常见的 CSS 实践?

c++ - 如果没有,创建一个包含数据的文本文件,然后读取它以检索数据

c++ - 在类(class)之间委派电话是不好的做法吗?

c++ - 如何链接我自己的 .so 文件而不是操作系统包 .so 文件?

c++ - "class ClassName;"放在其他类定义的头文件中是什么意思?

c++ - Pthread 在信号句柄中使用 pthread_cond_wait 阻塞

Django:sorl-thumbnail 和 easy-thumbnail 在同一个项目中

c++ - Requires-clause 出现在模板模板参数 : is this legal grammar? 之后

c++ - 初始化在构造函数中实现自身的类模板