2017-06-19 87 views
0

使用VS2013(VC2012)。如何通過這個簡單的例子在C++ 11中正確使用可變參數模板?

在閱讀了許多關於可變參數模板的答案並且沒有用我自己的代碼之後,我想問一下如何編譯/實現我的例子,它並不代表我的全部需要,但是我希望爲了使它更容易,更清潔,讓大家理解我的觀點。

我最好需要一個接收任意數量的(int,const char *元組)的函數,並從函數內部的這個列表中訪問任何元組。由於我相信通過互聯網閱讀這是不可能的,我試圖用任意數量的某個類來定義可變參數模板,該類將包含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

模板函數的定義必須在使用它的地方可見,除非出現異常情況。

你可以這樣做:

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)); 
    } 
}; 

然後在CPP文件:

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

或類似的東西。

+1

這也是值得注意到VS 2012實際上並不支持可變模板。它有一個解決方法來模擬標準庫的這種行爲,但在VS 2013或更高版本之前,可變參數模板並不真正受支持。 –

+0

@ChuckWalbourn,對不起,我在第一行有一個錯字,改爲VC2012(參考VS2013自然的工具集)。 –

+0

@Yakk感謝您的解決方案,我可以完美地理解它並幫助我學習更多。現在,我正在忙着讓我的代碼在應答之前工作。我還需要另一個要求,認爲它不會與模板發生衝突,但它仍然是我解決它的:具有va_arg解析(...)的最後一個常規可變參數。編譯器會對傳遞給variadic paramsInfo的參數的限制感到困惑。所以我在這裏把它解決了。 –

1

謝謝@Yakk。這裏展示了一部分我的真實代碼,以展示如何讓最後一個參數作爲arbritrary值傳遞(對於某些短語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); 
    } 
} 
相關問題