2017-12-04 21 views
0

I 작동이 코드 ... 지금까지 너무 좋아 한 :건물 constexpr 템플릿 구조체 (C++ 11)

struct _TYPEIDSTR {}; 
typedef _TYPEIDSTR *TYPE_ID; 
template<class T> _TYPEIDSTR _TYPE_ID; 

template<class T> constexpr TYPE_ID getTypeID() { return &_TYPE_ID<T>; } 

이 같은 주에 전화 :

constexpr TYPE_ID id1 = getTypeID<int>(); 
constexpr TYPE_ID id2 = getTypeID<int>(); 
RLOG("ID1 : " << id1); 
RLOG("ID2 : " << id2); 

작품 완벽하게, 그리고 getTypeID() 호출에 사용 된 각 유형에 대한 고유 한 식별자가 있습니다.

template<typename RES, typename... ARGS> struct _GlobalOverlayInfo { 
    bool _member; 
    RES(*_fn)(ARGS...); 
    size_t _nargs; 
    TYPE_ID _argIDs; 
    constexpr _GlobalOverlayInfo(RES(*fn)(ARGS...)) : 
    _member(false), 
    _fn(fn), 
    _nargs(sizeof...(ARGS)), 
    _argIDs {getTypeID<ARGS>()...} 
    {} 
}; 

template<typename RES, typename... ARGS> 
constexpr auto getOverlayInfo(RES(*fn)(ARGS...)) { 
    return & _GlobalOverlayInfo<RES, ARGS...>(fn); <<---ERROR1 
} 

이 기능을 사용하여 :

int pippo(int x) { 
    return 0; 
} 

과 같이 전화 :

constexpr auto x = getOverlayInfo(pippo); <<--- ERROR2 

내가 2를 얻을 지금은 함수에 대한 몇 가지 정보를 제공 구조체를 구축하려는 표시된 오류; ERROR1은 "임시 주소"를 가져 오지만 (컴파일 시간 평가가 아니어야합니다) ERROR2는 "오류 : '&'이 상수 표현이 아닙니다." 여러 가지 방법을 시도했지만 성공하지 못했습니다. 내가 틀린 곳? 이 결과를 얻는 방법이 있습니까 (C++ 11)? 필요한 모든 RES 및 ARGS ... 매개 변수에 대해 생성 된 고유 한 구조체에 대한 포인터입니다.

+0

템플릿 변수 ('_TYPE_ID')는 C++ 14 기능입니다. C++ 14 답변을 수락 하시겠습니까? – max66

+0

uhmm ... C++ 14에서 테스트 중이지만 C++ 11에서 실행해야합니다. 그러나 노력이 가치가 있다면 최신 GCC로 마이크로 컨트롤러 용 툴체인을 다시 만들려고 할 수 있습니다. 나는 가능한 한 여분의 RAM을 필요로하므로 컴파일 시간에이 정보를 필요로하므로 플래시 메모리에 저장해야한다. – Max

+0

이해가 잘 못됩니다 : ** type ** 또는 ('pippo')에 의존적 인 객체를 참조하는 conpile-time identificator가 필요합니까? – max66

답변

1

원하는 것을 이해하지 못했습니다.

어쨌든, 당신은 C++ 11 작품 원하는 (그리고 C++ 14 이상 피) 당신은 C++ 14 기능입니다

template<class T> _TYPEIDSTR _TYPE_ID; 

같은 템플릿 변수를 사용할 수없는 경우 .

constexpr 템플릿 식별자를 원할 경우 std::type_index을 사용할 수 있습니다.이 템플릿은 C++ 11부터 사용할 수 있습니다.

당신이 std::type_index을 사용할 수없는 경우는 ... 글쎄, 내가 상상할 수있는 최선은 포인터를 돌려 static 변수와 static 방법 템플릿 클래스입니다.

뭔가

template <typename> 
struct typeId 
{ 
    static constexpr int const val {}; 

    static constexpr int const * getId() 
    { return &val; } 
}; 

template <typename T> 
constexpr int const typeId<T>::val; 

처럼 당신은 constexpr 값을 얻을 수 있으며 differents의

함수의 경우를 들어
constexpr auto const idInt = typeId<int>::getId(); 
constexpr auto const idLong = typeId<long>::getId(); 

std::cout << (idInt != idLong) << std::endl; // print 1 

는 것을 확인할 수 있습니다 ...

기능 유형을 가지고 있으며, 하나의 기능을 수행 할 수 있습니다 템플릿 매개 변수가됩니다.

int foo (int) { return 0; } 
int bar (int) { return 0; } 
long baz (int, long, long long) { return 0L; } 

// ... 

constexpr auto idFoo = typeId<funcT<decltype(&foo), &foo>>::getId(); 
constexpr auto idBar = typeId<funcT<decltype(&bar), &bar>>::getId(); 
constexpr auto idBaz = typeId<funcT<decltype(&baz), &baz>>::getId(); 

std::cout << (idFoo != idBar) << std::endl; // print 1 
std::cout << (idFoo != idBaz) << std::endl; // print 1 
을 다음과 같이

그래서 당신이 함수에 대한 constexpr 식별자를 원하는 경우, 앞의 typeId을 사용하여,

template <typename Ft, Ft f> 
struct funcT 
{ }; 

을 다음과 같이 랩퍼를 작성 할 수 있습니다, 다른 기능과 다른 constexpr 값을 가져

+0

'getId' 기능을 제공하는 외부'funcT '로 아이디어를 좋아합니다. 나는이 접근법이 유형과 기능 모두를 다루기 위해 확장 될 수 있다고 생각한다. 그렇게하면 모든 유형을 수정할 필요가 없습니다 (불가능할 수도 있음). – Julius

+0

명확히하기 위해 PROGRAM MEMORY (일명 Flash, 내 경우에는)에서 생성 된 구조가 필요합니다. 여기에는 함수 params 및 반환 값에 대한 정보, 주소가있는 함수 포인터 및 기타 사소한 내용이 포함되어 있습니다. 나는 이미 그것을 가지고 있지만, RAM에 내 목적에 적합하지 않다. 최종 결과는 다음과 같이 호출 된 템플릿을 가진다 : 'Func ("name", function)' 은 구조체는 "name"포인터와 함께 배열에 저장 될 것입니다 (이번에는 런타임시 RAM에 저장됩니다). 컴파일 타임에 플래시 메모리에 구조를 배치하는 방법 외에도 모두 지금 작업 중입니다. – Max