2017-10-29 185 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