2012-08-01 5 views
0

런타임 차원 정보에서 Pointertype을 만듭니다C++ : 나는 이런 식으로 뭔가를 할

template<typename CType, unsigned int targetDimensions> struct GeneratePointerType 
{ 
    typedef typename GeneratePointerType<CType, targetDimensions-1>::type* type; 
    static const unsigned int dimensions = GeneratePointerType<CType, targetDimensions-1>::dimensions+1; 
}; 
template<typename CType> struct GeneratePointerType<CType, 0> 
{ 
    typedef CType type; 
    static const unsigned int dimensions = 0; 
}; 

Dictionary<int, GeneratePointerType<int, valueDimensions>::type > 

을 그래서 기본적으로 내가 포인터 타입의 컨테이너 템플릿을 인스턴스화 할,하지만 난의 포인터 수준을 모르는 런타임 전에 작성하기위한 포인터이므로 위의 접근 방식은 wocompile 할 수 없습니다. "dimensions"는 컴파일 타임 상수가 아니기 때문입니다.

의도 된 동작을 달성하는 방법 (C++ 11만의 기능이없는 순수한 C++ 03과 호환 됨)이 있습니까?

편집 : "실제 문제를 말해 줄 수 있다면 더 나은 해결책이 될 것입니다." "N을 런타임 값으로하는 N 차원 배열/객체 맵을 원한다면 Wierd. 유스 케이스를 상상할 수 없습니다." OK, 유스 케이스에 대해 몇 마디 말씀 드리겠습니다.

나는 기본적으로 C#이나 Java Dictionary generics처럼 행동하는 Template Dictionary라는 클래스를 가지고있다.

이 클래스는 C 라이브러리의 C++ 랩퍼 라이브러리에 사용됩니다.

나는 C++ 컨테이너 클래스의 인스턴스와 C 컨테이너 구조체의 인스턴스간에 데이터를 변환하는 변환 함수를 가지고 있습니다.

아시다시피 C++에서이 같은 컨테이너를 만들 수 있지만, 그래서 C는 제네릭이없는 :

CDictionary dic; 
dic.keytype = TYPECODE_INT; 
dic.valuetype = TYPECODE_INT; 
dic.valueDimensions = 2; 

을 지금 :

CI에
Dictionary<int, int**> dict; 

이처럼 할 필요를 C 사전을 C++ 사전으로 변환 할 때 C * 사전에 저장된 정보가 컴파일 시간 상수가 아니므로 올바른 수의 *를 생성하는 방법에 대해 고민하고 있습니다.

EDIT2 : 실제로 C lib가 네트워크를 통해 직렬화 된 데이터에서 해당 구조체를 생성 할 때 런타임 C++ 인터페이스에서 런타임 치수를 가져 오는 것이 중요하지 않습니다. 라이브러리의 컴파일 시점에서 알 수없는 것, 잠재적으로 또 다른 프로그래밍 언어의 다른 응용 프로그램에서 네트워크를 통해 들어오는 어레이의 배열 크기가 얼마나 될지, C++에서 구현 된 비 직렬화 구현은 사전에 대한 값 유형을 결정해야합니다 배열 차원에 대한 런타임 정보

EDIT3 : "이 구조를 사용하는 방법을 설명 할 필요가 있습니다. 질문을 올바르게 해석하지 못했고 질문에이 정보가 전혀 없기 때문입니다. 의사 코드는 당신이 달성하고자하는 것을 보여줍니까? " 공용 인터페이스에 전화 :

Dictionary<int, int*> dic; 
int* arr = new int[10]; 
dic.put(1, arr, a0); 
delete arr; 

send(dic); // dic gets serialized and sent over the netwowork 

직렬화 된 DIC를 수신 할 때, 내가 콜백에 전달하기 전에, 다시 역 직렬화하고 싶지 :

// read out typecodes and dimnesions from the serialized data 
// [...] 
// create the Dictionary from that info 
switch(valueTypeCode) 
{ 
    case TYPECODE_SHORT: 
     return new Dictionary<int, GeneratePointerType<short, valueDimensions>::type>[size](); 
    case TYPECODE_INTEGER: 
     return new Dictionary<int, GeneratePointerType<int, valueDimensions>::type>[size](); 
} 
// fill it with the deserialized payload afterwards 
// [...] 
+0

를 사용? –

+2

나는 이것을 원하지 않는다고 강력히 믿는다. 이것은 언급하지 않은 다른 문제에 대한 잘못된 해결책을 시도하는 것처럼 들립니다. 실제 문제를 말해 줄 수 있다면 더 나은 해결책이 될 것입니다. –

+0

명확히하기 위해,'N '이 _runtime_ 값인'N '차원 배열/객체의 맵을 원하십니까? 위어드. 나는 유스 케이스를 상상할 수 없다. –

답변

0

매개 변수 N이 알려져 있지 않은 경우 컴파일 할 때 정적 유형의 일부로 만들 수는 없습니다. 따라서 종류의 런타임 디스패치를 ​​사용해야합니다.

가능성 옵션 :

  1. 단지 똑같이 (기본 데이터를 캡슐화 연산자 과부하 및 다른 방법을 제공하는) 얕게 C 구조물을 감싸고 액세스

    class Dictionary { 
        CDictionary *inner; 
    public: 
        // C++ syntactic sugar here 
    }; 
    
  2. 경우 N이며, 적당한 값 (예 : N < 10이라고 가정 할 수 있음)으로 이상인 경우 템플릿을 인스턴스화 할 수 있습니다. cl 모든 유효한 N에 대해 엉덩이, 추상 인터페이스를 구현합니다. 그런 다음 템플릿 인스턴스화는 공용 (가상) 인터페이스와 팩토리 함수 만 노출하는 번역 단위에서 숨겨집니다. 실제 액세스는 항상`targetDimensions`과 정확히 일치 이후 왜의`dimensions` 회원이 그런 식으로 정의해야합니까 런타임 다형성

    class AbstractDictionary { 
    public: 
        virtual ~AbstractDictionary() = 0; 
        // virtual methods 
    }; 
    AbstractDictionary* wrap(CDictionary *); 
    
+0

to 1 : C 구조체를 래핑하는 것이 어떻게이 문제를 해결해야하는지 잘 모르겠습니다. to 2 .: 이론상 나는 이론적으로 N <= UINT_MAX 라고만 추측 할 수 있습니다. 실제로 N은 다차원 배열이 될 수있는 값의 차원 수이기 때문에 대부분의 경우 상대적으로 작을 것입니다. 따라서 0 (배열 없음)과 1 (1 차원)은 매우 일반적이며, 2와 3은 여전히 ​​일반적입니다. N이 높을수록 희귀해질 것입니다. 그러나 NI에 대한 실제 최대 값을 사용하지 않는다면 맹세 할 수 있습니다. Murphy 's law – Kaiserludi

+0

확실하지는 않습니다. C 구조체를 래핑하는 것이 어떻게 문제를 해결할 수있을 것입니까? ... 음, 문제가 무엇인지 알려주지 않았습니다. 아마도 C lib는 이미 잘 작동하기 때문에 얻을 수있는 것은 무엇입니까? – Useless

+0

C lib 인터페이스는 C 언어의 제약으로 인해 어려움을 겪고 있습니다. – Kaiserludi

관련 문제