2017-06-19 6 views
0

VS2013(VC2012)を使用する。この単純な例でC++ 11でバリデーションテンプレートを正しく使用する方法は?

バリデーショナルテンプレートに関する多くの回答を読んだ後、自分のコードで失敗した後で、私の例をコンパイル/達成する方法について質問したいが、これは私の必要性を表しているわけではないが、誰もが私のことを理解するのが簡単で清潔です。

私は、任意の量の(int、const char * tuples)を受け取り、関数内のこのリストから任意のタプルにアクセスする関数が必要なのが望ましいです。私はインターネットを介して読んだ後にこれが可能ではないと信じているので、int型とconst char型のメンバを含む任意のクラスの任意の量でバリデーションテンプレートを定義しようとしました。

それは私が別のファイルで定義から宣言を分離する必要が重要ですのでご注意ください。

phrases.h:

class CPhraseParamInfo { // Nothing, for easier example } 

class CPhrases 
{ 
    template<class... T> void Test(T... paramsInfo); 
} 

phrases.cpp

template<CPhraseParamInfo...> void CPhrases::Test(CPhraseParamInfo... param) 
{ // Nothing, for easier example } 

エラー(翻訳) :

error C2993: 'CPhraseParamInfo' : invalid type for the template parameter '__formal' without defined type 
error C3543: 'CPhraseParamInfo': doesn't contain a parameter pack 
error C2244: 'CPhrases::Test' : cannot match the function definition with an existent declaration 

可能であれば、私は最初の方法が好きです。私は十分に明確であることを望む。

ありがとうございます!

答えて

0

テンプレート関数の定義は、異常な場合を除いて、使用されるポイントで表示する必要があります。

あなたはこれを行うことができます:

void CPhrases::Test(CPhraseParamInfo* start, CPhraseParamInfo* end) 
{ 
    // Nothing, for easier example 
} 

または類似した何か:あなたのcppファイルに、次に

class CPhraseParamInfo { // Nothing, for easier example } 

class CPhrases { 
    void Test(CPhraseParamInfo* start, CPhraseParamInfo* end); 
    template<class... T> void Test(T... paramsInfo) { 
    CPhraseParamInfo buff[]={paramsInfo...}; 
    return Test(buff, buff+sizeof...(paramsInfo)); 
    } 
}; 

を。

+1

それはまた価値がありますVS 2012がバリデーショナルテンプレートを実際にサポートしていないことに注意してください。標準ライブラリのこの動作をエミュレートする回避策がありますが、バリデーションテンプレートはVS 2013以降には実際にはサポートされません。 –

+0

@ChuckWalbourn、申し訳ありませんが、最初の行に入力ミスがありました。代わりにVC2012を使用します(VS2013の自然なツールセットへの参照)。 –

+0

@ヤクあなたのソリューションをありがとう、私はそれを完全に理解することができ、もう少し学ぶことができました。今、私は答える前に自分のコードを動かすのに忙しかった。私はまた、考え方がテンプレートと衝突しないという別の要件を必要としましたが、やはり結局それを解決しました:va_arg解析(...)のための最後の正常な可変パラメータを持っていました。コンパイラは、渡されたパラメータの限界について混乱して、variadic paramsInfoに割り当てられます。だから私はここでそれをどのように解決しているのだろう。 –

1

ありがとう@Yakk。ここで私の実際のコードワークの一部を使って、最後のパラメータを(任意のフレーズva_args処理のために)渡す任意の値として使用する方法を示すための拡張された例を示します。ここで重要なのは、テンプレートのコールリスト(< CPhraseParamInfo、...>)で使用される可変引数クラスの同じ量を可変引数テンプレート関数を呼び出すことです:

phrases.h:

class CPhrases: 
{ 
    template<class... ParamInfo, typename... Arg> static void 
    LoadForPlayer(CHL2RP_Player *player, char *dest, int maxlen, const char *header, 
    const char *prependText, ParamInfo&... paramsInfo, Arg... args) 
    { 
     CPhraseParamInfo paramsInfoBuff[] = { paramsInfo... }; 
     LoadForPlayer(player, dest, maxlen, header, prependText, paramsInfoBuff, sizeof paramsInfoBuff, args...); 
    } 

    static void LoadForPlayer(CHL2RP_Player *player, char *dest, int maxlen, const char *header, const char *prependText, 
     CPhraseParamInfo *paramsInfoBuff, int paramCount, ...); 

    static FORCEINLINE void LoadRegionChat(CHL2RP_Player *player, char *dest, int maxlen, const char *talker, const char *message) 
    { 
     LoadForPlayer<CPhraseParamInfo, CPhraseParamInfo>(player, dest, maxlen, REGION_CHAT_HEADER, INDIAN_RED_CHAT_COLOR, 
     CPhraseParamInfo(CPhraseParamInfo::STRING, TEAM_CHAT_COLOR "%s" DEFAULT_CHAT_COLOR), CPhraseParamInfo(CPhraseParamInfo::STRING, "%s"), talker, message); 
    } 
} 
関連する問題