C++17下模板类适配MSVC与AppleClang的兼容问题
模板代码移植到AppleClang的兼容问题
近期将代码移植到MacOS/AppleClang平台时遇到了问题:大量在MSVC下可正常编译的模板代码,在Clang下编译失败(经确认是代码不符合C++标准),始终找不到合适的兼容方案。
原代码(MSVC可正常编译)
template<typename ValueType> class MemoryDataLayout { //Do stuff; }; template<typename LayoutType = MemoryDataLayout> class MemoryBufferView { public: using this_container = MemoryBufferView<LayoutType>; using layout_type = LayoutType; //Do stuff; };
Clang编译报错,原因是无法找到MemoryDataLayout类型——MemoryDataLayout是模板而非具体类型,MSVC的非标准扩展允许这种写法,但Clang严格遵循标准。
第一次修改尝试
将模板参数改为模板模板参数:
template<template <typename Type> class LayoutType = MemoryDataLayout> class MemoryBufferView { public: using this_container = MemoryBufferView<LayoutType>; using layout_type = LayoutType; //Do stuff; };
此时using layout_type = LayoutType;会报错,这符合标准逻辑:LayoutType是模板,需要传入类型参数才能成为具体类型,但当前上下文没有可用的类型参数。
已知的标准兼容方案
可以改为同时接收类型参数和模板模板参数:
template<typename Type, template <typename> class LayoutType = MemoryDataLayout> class MemoryBufferView { public: using this_container = MemoryBufferView<LayoutType>; using layout_type = LayoutType<Type>; //Do stuff; };
但这需要修改代码库中大量实例化代码,因此希望能仅保留单个模板参数以保持兼容性(如果可行的话)。另外,项目只能使用C++17,无法升级到更高标准。
补充细节
代码库中使用默认布局实例化该类的方式为:
MemoryBufferView<char> m;
目前找到的兼容方案
以下方案能让大部分使用默认布局的代码保持兼容,但自定义布局的调用代码仍需修改:
template<typename ValueType> class MemoryDataLayout { //Do stuff; }; template<typename T, template<typename> class LayoutType = MemoryDataLayout> class MemoryBufferView { public: using this_container = MemoryBufferView<T, LayoutType>; using layout_type = LayoutType<T>; //Do stuff; }; void f(){ MemoryBufferView<char> m; // 默认布局调用无需修改 }
我已经接受了这个方案,它简洁且贴合需求,但仍好奇是否存在更优解。
[最终更新]
最终采用了上述方案,它更简洁且更贴合我们的需求。
内容的提问来源于stack exchange,提问作者LarrxX
相关产品推荐
相关产品推荐

