Emscripten如何关闭显式特化不能包含存储类的警告
问题根因
C++标准规定,类内部定义的显式模板特化不能额外指定存储类说明符(包括static),特化会隐式继承主模板的存储类属性。Clang的警告是符合标准要求的,而MSVC在此处的实现不符合标准,才会出现删了static就报错的冲突。
可行解决方案
方案1:将特化移至类外(推荐,完全符合C++标准)
这是兼容性最好的实现方式,无需区分编译器,代码示例:
#include <iostream> #include <string> struct Test { template<typename T> static inline void Dump(const T& value) { std::cout << "[generic] = '" << value << "'\n"; } }; // 特化移至类外命名空间作用域,无需加static,保留inline即可 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; }
说明:类外特化会自动继承主模板的static属性,Clang不会触发警告,MSVC也能正常编译运行。
方案2:使用编译器宏做条件编译
如果必须保留类内特化的写法,可以通过宏区分编译器,仅在MSVC下保留static关键字:
struct Test { template<typename T> static inline void Dump(const T& value) { std::cout << "[generic] = '" << value << "'\n"; } template<> #ifdef _MSC_VER static #endif inline void Dump<std::string>(const std::string& value) { std::cout << "[std::string] = '" << value << "'\n"; } };
方案3:屏蔽Clang对应警告(不推荐,仅临时过渡使用)
如果暂时不想修改代码,可以先拿到警告对应的准确选项:
- 编译时添加
-fdiagnostics-show-option参数:emcc -fdiagnostics-show-option a.cpp - 警告输出末尾会显示对应的选项名,格式为
[-Wxxx] - 后续编译时添加
-Wno-xxx参数即可屏蔽该警告
内容的提问来源于stack exchange,提问作者Петр Петров
相关产品推荐
相关产品推荐

