使用typedefs的模板专用化

Template specialization using typedefs

本文关键字:专用 typedefs 使用      更新时间:2023-10-16

在学习Vulkan时,我在VulkanCookbook中发现了一些代码。在VulkanCookbook中,作者编写了手动导入Vulkan函数和类的代码。嗯,我一直在慢慢地将其转换为Vulkan的LunarG SDK,我在64位以下的VkFence中遇到了一个问题,它将typedef改为VkFence_T*,这很好,除了32位之外,它的typedef都改为uint64_T,这给使用类似于下面代码的VkDestroyer带来了问题

#include <iostream>
#include <stdint.h>
typedef uint64_t A;
typedef uint64_t B;
template<typename T>
class Handler
{
void DestroyObject( T parent );
};
template<>
inline void Handler<A>::DestroyObject(A object) {
std::cout << "destroy type A" << std::endl;
}
template<>
inline void Handler<B>::DestroyObject(B object) {
std::cout << "destroy type B!" << std::endl;
}
int main()
{}

有什么好的方法来处理这个问题吗?或者我必须重新编写所有的示例代码来手动删除对象吗?如果可能的话,我想在32位下编译。

很抱歉,如果这个问题在其他地方被问到,我找不到,因为谷歌总是提供部分模板和其他非相关主题。我确实理解编译器查看_A和_B的代码的问题,只将其视为uint64_t,而不考虑它们的名称不同,这会导致DestroyObject重载用于相同的模板类型,从而导致重新定义错误。

编辑:修复了使用无效命名的代码,因为这实际上不是核心问题。

C++没有强类型定义。类型别名只是现有类型的另一个名称,在使用时与它所别名的类型完全等效。

您需要AB是实际类型,而不是别名,它们都与uint64_t有关系。只要你把自己约束在积分类型中,你就可以从它们中构造出新的不同类型。

解决方案是一个枚举,并为其指定了底层类型。

#include <type_traits>
template<typename E>
using argument_t = std::conditional_t<std::is_enum<E>::value,
std::underlying_type_t<E>,
E>; 
template<typename T>
class Handler
{
void DestroyObject( argument_t<T> parent );
};
enum A : uint64_t {};
enum B : uint64_t {}; 
template<>
inline void Handler<A>::DestroyObject(uint64_t object) {
std::cout << "destroy type A" << std::endl;
}
template<>
inline void Handler<B>::DestroyObject(uint64_t object) {
std::cout << "destroy type B!" << std::endl;
}

上面的工作原理是这样的:

  • argument_t实用程序检查E是否是枚举,并为其提供基础类型。否则,它将返回到E本身。

  • 主模板接受T,并在需要时转换参数。

  • 由于AB现在是不同的类型,您可以专门处理每种类型。函数接受基础类型作为参数。

你几乎是对的。。。上述函数Handler<_A>::DestroyObject(_A object)Handler<_B>::DestroyObject(_B object)实际上是模板化成员函数的具体实例。因为作者没有提供这个函数的通用版本,所以在尝试用uint32_t实例化类时遇到了问题。简单的修复方法是编写一个template<> void Handler<uint32_t>::DestroyObject(uint32_t o)函数。没有更多的背景,我无法提供更好的建议。

模板无法区分作为类型参数封装的AB

可能有手动清理物体的替代方案,但你的问题太模糊了,而且集中在寻找一种方法来让一个不可行的solation工作,以确定你的问题到底是什么

也许你必须使用与类型本身不同的东西在类型之间进行伪装。