在学习Vulkan时,我在VulkanCookbook中遇到了一些代码。在VulkanCookbook中,作者编写代码以手动导入Vulkan函数和类。好吧,我一直在慢慢将它转换为LunarG的Vulkan SDK,我在64位VkFence下遇到了一个问题,它输入了VkFence_T *这很好,除了32位之外它是& #39; s typedef' d as 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重载用于导致重定义错误的相同模板类型。 p>
编辑:使用无效命名修复代码,因为这实际上不是核心问题。
答案 0 :(得分:4)
C ++没有强大的typedef。类型别名只是现有类型的另一个名称,在使用时完全等同于别名的类型。
您需要A
和B
作为实际类型,而不是别名,它们都与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
,并根据需要转换参数。
由于A
和B
现在是不同类型,您可以专注于每种类型。该函数接受基础类型作为参数。
答案 1 :(得分:0)
你差不多......上面的函数Handler<_A>::DestroyObject(_A object)
和Handler<_B>::DestroyObject(_B object)
实际上是模板化成员函数的具体实例。因为作者没有提供此函数的通用版本,所以您遇到的问题是尝试使用uint32_t实例化该类。简单的解决方法是编写template<> void Handler<uint32_t>::DestroyObject(uint32_t o)
函数。没有更多的背景,我无法提供更好的建议。
答案 2 :(得分:0)
模板无法区分被粘贴A
和B
作为类型参数。
可能有其他方法可以手动清理对象,但是你的问题太模糊了,而且专注于找到一种方法让一个不可行的解决方案来确定你的问题到底是什么。
可能你必须使用与类型本身不同的类型来区分类型。