Emscripten:如何禁用警告:显式专业化不能有存储 class

Emscripten: how to disable warning: explicit specialization cannot have a storage class

我正在使用最新的 Emscripten 编译器构建我的程序。 它基于 Clang 版本 14。实际上它是一个小测试程序,如下所示:

#include <iostream>

struct Test {
    template<typename T>
    static inline void Dump(const T& value) {
        std::cout << "[generic] = '" << value << "'\n";
    }

    template<>
    static inline void Dump<std::string>(const std::string& value) {
        std::cout << "[std::string] = '" << value << "'\n";
    }
};

int main() {
    std::string text = "hello";
    Test::Dump(text);
    return 0;
}

当我用 Emscripten 编译器构建它时,我收到了警告:

D:\em_test>emcc a.cpp
a.cpp:10:24: warning: explicit specialization cannot have a storage class
    static inline void Dump<std::string>(const std::string& value) {
    ~~~~~~~            ^
1 warning generated.

如果我只是从 void Dump<std::string> 行删除 static 关键字 那么就不会有警告。但是这段代码会导致编译错误 Visual Studio:

D:\em_test\a.cpp(17,11): error C2352: 'Test::Dump': illegal call of non-static member function

但是这个错误是意料之中的,而且很明显。 我想写一个跨平台的程序。 所以,我想我应该在 Emscripten 中简单地禁用这个警告。 但是,我找不到任何 Emscripten(基于 clang 版本 14) 命令行选项! 我正在征求意见。

实际上我尝试使用 -Wno-static-inline-explicit-instantiation 命令行选项但它没有帮助:

D:\em_test>emcc -Wno-static-inline-explicit-instantiation a.cpp
a.cpp:10:24: warning: explicit specialization cannot have a storage class
    static inline void Dump<std::string>(const std::string& value) {
    ~~~~~~~            ^
1 warning generated.

然而,我在 Clang 版本 13 用户手册中看到关于 -Wstatic-inline-explicit-instantiation 选项的描述,但它是关于一个稍微不同的警告文本。 另外,似乎 Clang 版本 14 尚未完全发布,因此,没有 public Clang 版本 14 用户手册。

我找不到任何 Emscripten 或 Clang 命令行选项来禁用上述警告。 有人可以帮我吗?

不能将(静态和非静态)函数模板的显式特化放入 class 定义中。 只需将其放入封闭的命名空间(即 class 之后的某处):

#include <iostream>

struct Test {
    template <typename T>
    static inline void Dump(const T& value) {
        std::cout << "[generic] = '" << value << "'\n";
    }
};
// Notice Test::
template <>
inline void Test::Dump<std::string>(const std::string& value) {
    std::cout << "[std::string] = '" << value << "'\n";
}

int main() {
    std::string text = "hello";
    Test::Dump(text);
    return 0;
}

inline 对于 in-class 函数定义从来都不是必需的,但它对成员变量有不同的含义。 inline for out-class 在头文件中是必需的,因为显式特化不再是模板。