2017-10-29 3 views
3

Vulkan을 배우는 동안 VulkanCookbook에 몇 가지 코드가 나타났습니다. VulkanCookbook에서 저자는 Vulkan 함수와 클래스를 직접 가져 오기위한 코드를 작성합니다. 글쎄 난 천천히 Vulkan을위한 LunarG의 SDK로 변환 해왔다. 64 비트 VkFence에서 VkFence_T *에 문제가 생겼다. VkFence_T *에 문제가 생겼다. 32 비트에서는 typedef가 아닌 uint64_t가된다. 이 문제를 처리하거나 내가 가서 손으로 객체를 삭제하는 모든 예제 코드를 재 작업해야 할 어떤 좋은 방법이typedef를 사용한 템플릿 전문화

#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() 
{} 

아래에 유사한 코드를 사용 VkDestroyer에 대한 문제? 가능한 경우 32 비트 미만으로 컴파일하려고합니다.

죄송합니다.이 질문은 Google에서 언제나 부분적으로 템플리트를 작성하고 다른 비 관련 항목을 찾았 기 때문에 찾을 수 없었습니다. 그리고 컴파일러가 _A와 _B를보고있는 코드의 문제점을 이해하고 다른 이름을 지정하지 않고 uint64_t를 처리하면 DestroyObject 오버로드가 재정의 오류를 일으키는 동일한 템플리트 유형에 해당됩니다.

편집 : 실제로 핵심적인 문제가 아니므로 잘못된 이름 지정을 사용하여 코드를 수정했습니다.

+0

@StoryTeller (a)는 문제를 해결하기 위해 어쨌든 존재합니까? (b) 내가 테스트 한 코드에서 실수로 해당 코드의 이전 버전을 붙여 넣었습니다. – Cieric

+0

유형은 완전하게 필수 항목입니까? – StoryTeller

+0

@StoryTeller 예, 20 명이 있습니다. 그들이 어떻게 작동하는지에 따라 나는 32 비트 모드에서 64 비트 포인터처럼 사용된다고 생각한다. – Cieric

답변

3

C++에는 강력한 typedef가 없습니다. 유형 별명은 기존 유형에 대한 또 다른 이름이며 별명이 사용될 때 완전히 별명입니다.

ABuint64_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 유형을 기반으로 실행하려면 다른 코드가 필요하다는 것입니다. 전달 된 형식에 따라 결과 코드가 달라야하기 때문에'템플릿 <> void Handler :: DestroyObject (uint32_t o)'가 작동하지 않습니다. – Cieric

0

은 템플릿 형식 매개 변수로 AB을 pasded되고 구별 할 방법이 없습니다.

개체를 수동으로 정리하는 대안이있을 수 있지만 질문이 너무 모호하고 문제가 실제로 무엇인지 결정할 수있는 실행 불가능한 단독 작업을 수행하는 방법을 찾는 데 집중합니다.

아마도 유형 자체와 다른 유형을 사용하여 유형을 구분하지 않아야합니다.

+0

Vulkan을 사용하는 방법을 배울 필요가 없으므로 실제로 코드를 크게 변경하고 싶지는 않습니다. 문제가 있으므로 64 비트로 컴파일하면 문제가 계속됩니다. – Cieric