1

私はメタプログラミングが初めてで、タブを使用すると const 関連の問題が発生します。

いくつかの「タイプ」があるとしましょう。型ごとにバージョンが異なり、各型のすべてのバージョンに対応できるものとします。そのために、型に関する標準情報を含む構造体と、各バージョンの情報を含む配列を使用します。

問題は、各タイプのバージョン数が同じではないということです。また、バージョン番号はそれほど高くないため、上記のテーブルの動的割り当てを使用しないことを好みます。しかし、静的割り当てを行う場合は、構造体のインスタンスごとに同じサイズのテーブルが必要です。つまり、最高のバージョン値を取得し、それを配列のサイズとして使用する必要があります。

ここに来ました:コンパイル時に最高のバージョン値を与える小さなメタプログラミングテンプレートを作成したいので、各タイプの必要な情報を確実に含む配列の固定サイズを持つことができます。しかし、コンパイルエラーが発生します。

問題を再現する簡略化されたサンプル コードを次に示します (エラーが続きます)。

#include <stdio.h>

// change values here
#define VERSION_ALPHA 3
#define VERSION_BETA 5
#define VERSION_GAMMA 2

// different available types
enum TYPES
{
    T_ALPHA = 0,
    T_BETA,
    T_GAMMA,

    T_COUNT, // number of types
};

// to access versions more easily from code
static const int typeVersions[T_COUNT] =
{
    VERSION_ALPHA,
    VERSION_BETA,
    VERSION_GAMMA
};

// this meta is used to get the highest version values between all types
template<int i>
class HighestVersion
{
private:
    // version of type -1
    enum
    {
        PREVIOUS = HighestVersion<i-1>::VALUE
    };

public:
    // current max value
    enum
    {
        VALUE = (typeVersions[i] > PREVIOUS ? typeVersions[i] : PREVIOUS)
    };
};

// first version
template<>
class HighestVersion<0>
{
public:
    // current max value
    enum
    {
        VALUE = typeVersions[0]
    };
};

// highest version macro
#define HIGHEST_VERSION HighestVersion<T_COUNT>::VALUE

// holds info about a single type
struct TypeInfo
{
    char * s_pName; // name of the type as string
    unsigned int s_Flags[HIGHEST_VERSION]; // flags for each available version of this type
};


int main()
{
    // instanciate
    TypeInfo infos[T_COUNT];

    // do stuff, set name, load flags....
    /*...*/

    // for test purpose, print max version value (should print 5 in this situation)
    printf("%d\n", HIGHEST_VERSION);
}

コンパイラは言う:

error C2057: expected constant expression

@ 台詞

VALUE = (typeVersions[i] > PREVIOUS ? typeVersions[i] : PREVIOUS)

VALUE = typeVersions[0]

コンパイラは、テーブルの内容が一定ではないと言っているようです。その場合、テーブルが定数ではないポインターとして解釈されるためだと思います(したがって、ポインターが変更された場合、内容は同じではありません)。スクリプトを使用できるように修正する方法はありますか? ユーザーがそのテーブルのサイズを手動で設定する必要がなくなります...

前もって感謝します :)

4

3 に答える 3

1

jrok が言ったように、静的配列でこれを行うことはおそらく不可能です。ただし、適切に準拠した C++11 コンパイラがある場合は、型バージョンごとに特性特化を作成する必要もありません。

あなたは VC++ を使用しており、おそらくそれにコミットしていると思います。残念ながら、あなたが持っている、または現在手にしている唯一の適切に準拠した C++11 コンパイラは VC++ 2013 Preview です。それを使用できる場合は、プログラムの次の変更によって示される単純な可変個引数テンプレート ソリューションが機能します。

#include <stdio.h>

// change values here
#define VERSION_ALPHA 3
#define VERSION_BETA 5
#define VERSION_GAMMA 2

// different available types
enum TYPES
{
    T_ALPHA = 0,
    T_BETA,
    T_GAMMA,
    T_COUNT, // number of types
};

template<int ...Versions>
struct versions_list
{
    static_assert(sizeof ...(Versions),
        "Cannot have 0 versions");
};

template<int Only>
struct versions_list<Only>
{
    static const int max = Only;
};

template<int First, int Last>
struct versions_list<First,Last>
{
    static const int max = First > Last ? First : Last;
};

template<int First, int Second, int ...Rest>
struct versions_list<First,Second,Rest...>
{
    static const int tail_max = versions_list<Second,Rest...>::max;
    static const int max = First > tail_max ? First : tail_max;
};

// Update your version list here:
typedef versions_list<VERSION_ALPHA, VERSION_BETA, VERSION_GAMMA> typeVersions;

#define HIGHEST_VERSION typeVersions::max


// holds info about a single type
struct TypeInfo
{
    char * s_pName; // name of the type as string
    unsigned int s_Flags[HIGHEST_VERSION]; // flags for each available version of this type
};


int main()
{
    // instanciate
    TypeInfo infos[T_COUNT];

    // do stuff, set name, load flags....
    /*...*/

    // for test purpose, print max version value (should print 5 in this situation)
    printf("%d\n", HIGHEST_VERSION);
}

ここでは、HIGHEST_VERSIONマクロは本当に無意味です。その定義を削除して、出現箇所をすべてtypeVersions::max.

ところで、本当に C++ プログラムで C++ API ではなく C の API を使用したい場合は、stdio厳密 iostreamには を使用する必要があります。#include <cstdio>#include <stdio.h>

于 2013-08-04T11:49:32.717 に答える