2017-12-04 15 views
0

私が働くこのコード、...これまでのところは良いしている:構築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++ 14以降を避けるため)C++ 11で作品にしたい場合は、C++ 14の機能です

template<class T> _TYPEIDSTR _TYPE_ID; 

のようなテンプレート変数を使用することはできません。

constexprテンプレート識別子を使用する場合は、std::type_indexを使用できます。これはC++ 11以降で使用できます。

std::type_indexを使用できない場合は、static変数とそのポインタを返すメソッドstaticを持つテンプレートクラスを想像してみてください。あなたはconstexpr値を取得することができますし、貴様機能ケースの場合

constexpr auto const idInt = typeId<int>::getId(); 
constexpr auto const idLong = typeId<long>::getId(); 

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

されていることを確認することができます

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; 

よう

何か...

関数型とすることができ、単一の機能を持っていますテンプレートパラメータです。

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とも呼ばれます)で作成された構造体が必要です。関数のパラメータと戻り値、アドレスを持つ関数ポインタ、その他の小さなものを含んでいます。 私はすでにそれを持っていますが、私の目的には最適ではないRAMにあります。 最後に、 'Func(" name "、function)' は次のように呼び出されたテンプレートを持っています。構造体は "name"ポインタとともに配列に格納されます(実行時にはRAMに格納されます)。 コンパイル時にフラッシュメモリに構造体を配置する方法の他に、現在、すべてが動作しています。 – Max

関連する問題