0

私はコンストラクタをうまく特殊化することができます:

template < typename TType >
class Field
{
public:
    Field( const Msg& )
        : _type( TType() )
    { }

protected:
    TType    _type;
};

template < >
Field < double >::Field( const Msg& msg )
    : _type( msg.extractDouble() )
{
}

template < >
Field < int >::Field( const Msg& msg )
    : _type( msg.extractInt() )
{
}

ただし、次のような型以外の引数を取るテンプレートでも同じことを行う必要があります。

template < const char* pszName, typename TType >
class Field
{
public:
    Field( const Msg& )
        : _type( TType() )
    { }

    static void setup( const Descriptor& d ) { // called once to setup _nIndex based on Descriptor and pszName 
    static int  index() { return _nIndex; }

protected:
    TType              _type;   // This class can only be sizeof TType in size

    static int         _index;
};

template < >
Field < ??, ?? >::Field( const Msg& msg )     // This doesn't compile
    : _type( msg.extractDouble( index() ) )
{
}

template < >
Field < ??, ?? >::Field( const Msg& msg )        // This doesn't compile
    : _type( msg.extractInt( index() ) )
{
}

これを行うためのトリックはありますか?実行時に setup() 中に const char 名を渡すことができると思います。しかし、オブジェクト自体が支援なしで知っていれば、それは素晴らしいことです。

4

1 に答える 1

3

ここでの問題は、関数を部分的に特殊化できないことと、コンストラクターが関数であることです。それらを完全に特化するか、まったく特化しないかのどちらかです。

この問題の一般的な解決策は、タグディスパッチを使用することですが、特定のユースケースでは少し簡単です...static_cast

template < typename TType, int n >
class Field
{
public:
    Field( float f )
        : _type( static_cast<TType>(f) )
    { }

protected:
    TType    _type;
};

デモ

于 2016-11-04T20:40:36.960 に答える