constexpr 是否应该暗示内联专业化? constexpr 函数

问题描述

在 MSVC2019 16.10 中,当包含具有静态 constexpr 类函数的特化的标头时,我开始收到“已定义”错误。最小复制案例:

#pragma once

template <typename T>
struct foo
{
    static constexpr void bar() {}
};

template <>
constexpr void foo<int>::bar() {}

在两个源文件中包含这个头文件给出:

Source2.obj : error LNK2005: "public: static void __cdecl foo<int>::bar(void)" (?bar@?$foo@H@@SAXXZ) already defined in Source1.obj

据我所知,在这种情况下, constexpr 应该暗示内联。添加内联或更改为 consteval 工作。也对全局模板函数链接进行专门化。它适用于早期版本的 Visual Studio,并且 clang 也没有问题。这是编译器错误吗?

解决方法

这是编译器错误吗?

好吧,Microsoft 的 own documentation 会建议是的:

constexpr 函数

...
constexpr 函数或构造函数隐式为 inline