提问人:LarrxX 提问时间:9/22/2023 最后编辑:LarrxX 更新时间:9/23/2023 访问量:61
模板不完整模板的别名类型
Aliasing type of incomplete template of template
问:
几天来我一直在为此苦苦挣扎。我正在将一些代码移植到 MacOS/AppleClang,我们有非常繁重的模板化代码,这些代码在 MSVC 上正确构建,但在 clang 上失败(可以理解,因为在阅读之后,我们的代码不符合标准)。但我真的找不到一种方法来正确地做到这一点。
下面是原始代码,可在 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
但是,如果我这样写:
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;
理想情况下,我知道我应该写作,但从这个上下文中似乎看不到类型。using layout_type = LayoutType<Type>;
我知道我可以这样写出来:
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;
}
但这仅在使用默认布局调用 MemoryBufferView 时有效(否则我必须更改调用)。
我可以忍受这一点,但出于好奇,如果有更好的东西,我很乐意阅读:)
[最终编辑]
我最终使用了我上面提出的解决方案,它更干净,更准确地满足我们想要的情况。
答:
您可以制作别名模板layout_type
template<template <typename Type> class LayoutType = MemoryDataLayout>
class MemoryBufferView
{
public:
using this_container = MemoryBufferView<LayoutType>;
template<typename ValueType>
using layout_type = LayoutType<ValueType>;
//Do stuff;
};
评论
ValueType
Type
Type
ValueType
Type
ValueType
MemoryBufferView
MemoryDataLayout<char>
当前代码从未使用该模板参数的默认值。MSVC 有点不合规,因为它将模板的一些检查推迟到实例化时间。 不使用默认的模板参数,则完全替换为 。如果您认为会影响 .MemoryBufferView<char>
char
MemoryDataLayout
MemoryBufferView<char>
您可以进行的影响最小的更改是删除不正确的默认参数:
template<typename LayoutType>
class MemoryBufferView
{
public:
using this_container = MemoryBufferView<LayoutType>;
using layout_type = LayoutType;
//Do stuff;
};
Clang 会接受它,并且您不会更改现有代码的行为。
评论
/permissive-
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;
}
我最终使用了这种方法,这种方法更正确,实际上符合原始开发人员的意图。感谢大家的帮助和投入。
评论
MemoryBufferView<char>
char
MemoryDataLayout<T>
MemoryBufferView<char>
应该是 MemoryBufferView<MemoryDataLayout<char>>' 我想强调的是,这种恐怖不是我的代码,我只是想让它达到规范:)template<typename Type, template <typename> class LayoutType = MemoryDataLayout> class MemoryBufferView