2017-10-29 148 views
3

在学习Vulkan时,我在VulkanCookbook中遇到了一些代码。在VulkanCookbook中,作者编写代码来手动导入Vulkan函数和类。好吧,我一直在慢慢地将它转换为Vulkan的LunarG SDK,并且我在64位VkFence中遇到了一个问题,它将VkFence_T *键入到VkFence_T *中,这很好,除了32位外,它的typedef是dint64_t,对于VkDestroyer问题,它使用类似的代码如下使用typedefs的模板专门化

#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重载针对导致重定义错误的相同模板类型。

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

+0

@StoryTeller(a)是否有解决这个问题的方法? (b)我在我测试的代码中改变了我意外地粘贴了该代码的旧版本。 – Cieric

+0

类型是否严格整数? – StoryTeller

+0

@StoryTeller是的,有20个。基于它们的工作方式,我认为它们在32位模式下的使用方式类似于64位指针。 – Cieric

回答

3

C++没有强壮的typedef。类型别名只是现有类型的另一个名称,在使用时与其别名类型完全相同。

您需要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都是不同现在类型,你可以专注于每个。该函数接受基础类型作为参数。

+0

此解决方案实际上非常好,但我不确定是否更改A和B类型在我的情况下是可行的,因为它们与库中包含的头部分开。然而,当你的回答回答这个问题时,我会将其标记为正确,并继续以64位编译,而不存在问题。 – Cieric

0

你几乎没错吧......以上功能Handler<_A>::DestroyObject(_A object)Handler<_B>::DestroyObject(_B object)实际上是模板成员函数的具体实例。由于作者没有提供此函数的通用版本,因此尝试使用uint32_t实例化类时遇到了问题。简单的解决方法是编写一个template<> void Handler<uint32_t>::DestroyObject(uint32_t o)函数。没有更多的背景,我不能提供更好的建议。

+0

问题是typedef A和B是相同的核心类型,但我需要不同的代码来运行基于typedef类型而不是核心类型。并且'template <> void Handler :: DestroyObject(uint32_t o)'不能工作,因为生成的代码需要根据传入的类型而有所不同。 – Cieric

0

没有方法为一个模板被pasded AB作为类型参数之间进行区分。

可能有手动清理对象的替代方法,但您的问题过于模糊,并且专注于找到一种方法来确定您的问题真正存在的问题。

也许你必须在类型之间使用不同于类型本身的类型。

+0

我主要不希望主要更改代码,因为我想实际学习如何使用Vulkan而没有太多麻烦,但是因为这是一个问题,我将继续以64位编译,这确实有效。 – Cieric