Reputation: 85
Using VS2013 (VC2012).
After reading many answers about variadic templates and failing with my own code, I want to ask about how to compile/achieve my example, which does not represent my whole need but in place I prefer to put in order to make it easier and cleaner for everyone to understand my point.
I preferably need a function which receives an arbitrary amount of (int, const char * tuples), and access any tuple from this list inside the function. Since I believe after reading over Internet this is not possible, I tried defining the variadic template with an arbitrary amount of a certain class which would contain the int and const char* members, and it fails.
Please note it's important I want to separate the declaration from the definition in different files:
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 }
Errors (translated):
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
Remember I'd prefer the first method, if possible. I hope I was clear enough.
Thanks!
Upvotes: 0
Views: 460
Reputation: 85
Thanks @Yakk. Here is expanded example with part of my real codework in order to show how to allow a last parameter to be used as arbritrary values passing (for certain phrase va_args processing), if anyone finds it useful. The key here is to call the variadic template function with the same amount of variadic class used on the template call list (< 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);
}
}
Upvotes: 1
Reputation: 275956
The definition of a template function must be visible at the point where it is used, barring unusual cases.
You could do this:
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));
}
};
then in your cpp file:
void CPhrases::Test(CPhraseParamInfo* start, CPhraseParamInfo* end)
{
// Nothing, for easier example
}
or something similar.
Upvotes: 0