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

Posted

技术标签:

【中文标题】Emscripten:如何禁用警告:显式专业化不能有存储类【英文标题】:Emscripten: how to disable warning: explicit specialization cannot have a storage class 【发布时间】:2021-10-11 11:14:19 【问题描述】:

我正在使用最新的 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&lt;std::string&gt; 行中删除 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 似乎还没有完全发布,因此,没有公开的 Clang 版本 14 用户手册。

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

【问题讨论】:

【参考方案1】:

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

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

【讨论】:

以上是关于Emscripten:如何禁用警告:显式专业化不能有存储类的主要内容,如果未能解决你的问题,请参考以下文章

在 emscripten 中禁用链接 libc

(编辑)如何在Windows中导出模板专业化,并在cpp文件中声明源

显式 void 指针作为函数参数

如何在chocolatey上禁用显式代理?

如何禁用“'NSInteger' 类型的值不应用作格式参数;改为将显式强制转换添加到 'long'”

显式模板特化