Although this code is not standard compliant, you can quite simply change it. Here is a modified version of MetaData
class:
class MetaData
{
public:
template<int ID, class T>
void addVar(string varNames)
{
// do smth
}
template<class MSGT, int ID = std::tuple_size<typename MSGT::values_type>::value - 1>
struct addVarDesc
{
static void exec(MetaData& md, string varNames)
{
typedef typename std::tuple_element<ID, typename MSGT::values_type>::type varType;
md.addVar<ID, varType>(varNames);
addVarDesc<MSGT, ID-1>::exec(md, varNames);
}
};
template<class MSGT>
struct addVarDesc<MSGT, 0>
{
static void exec(MetaData& md, string varNames)
{
}
};
template<class MSGT>
static MetaData createMetaData(string varNames)
{
MetaData md;
MetaData::addVarDesc<MSGT>::exec(md, varNames);
return md;
}
};
The problem can also be solved in another way - using a wrapper around MetaData::addVarDesc::exec
method:
class MetaData
{
public:
template<int ID, class T>
void addVar(string varNames)
{
// do smth
}
template<int ID, class MSGT>
struct addVarDescImpl
{
static void exec(MetaData& md, string varNames)
{
typedef typename std::tuple_element<ID, typename MSGT::values_type>::type varType;
md.addVar<ID, varType>(varNames);
addVarDescImpl<ID-1, MSGT>::exec(md, varNames);
}
};
template<class MSGT>
struct addVarDescImpl<0, MSGT>
{
static void exec(MetaData& md, string varNames)
{
}
};
template<class MSGT>
static void addVarDesc(MetaData& md, string varNames)
{
addVarDescImpl<std::tuple_size<typename MSGT::values_type>::value - 1, MSGT>::exec(md, varNames);
}
template<class MSGT>
static MetaData createMetaData(string varNames)
{
MetaData md;
addVarDesc<MSGT>(md, varNames);
return md;
}
};
Both methods may be wrong if such back order (from last to first tuple element) is not suitable for you. But they can be modified to account for this.