我正在尝试在地图中复制数据库表,其中主键是map的键,其余列是boost:vector的实例。我是新手以及可变参数模板。我曾尝试编写一个包装器,但它只适用于固定数量的列。以下是代码
#include <boost/container/vector.hpp>
#include <iostream>
#include <string>
#include <map>
#include <type_traits>
typedef boost::container::vector<std::string> MAPPED_COLS;
typedef std::map <int, MAPPED_COLS > TABLE ;
typedef std::map <int, MAPPED_COLS > ::iterator ROW_ITER;
typedef std::string str;
template <typename str>
class MappedTable
{
private:
TABLE mapTable;
MAPPED_COLS cols;
ROW_ITER row;
std::string scTableName;
int iRows;
int iCols;
public:
MappedTable() { iCols=3; }
MappedTable(int iNumCols) { iCols=iNumCols;}
~MappedTable() { }
template <str>
void fnRowCols() //termination version
{
}
template <str>
void fnCols(const str& scCol2, const str& scCol3,...)
{
if(cols.size()>=iCols)
{
cols.erase (cols.begin(),cols.begin()+iCols);
}
cols.push_back(scCol2);
fnCols(scCol3,...);
}
template <str>
void fnMapRow(int iCol1,const str& scCol2,...)
{
fnCols(scCol2,...);
mapTable[iCol1]=MAPPED_COLS(cols);
}
MAPPED_COLS& fnGetRow(int iFindKey)
{
row=mapTable.find(iFindKey);
if(row!=mapTable.end())
return (row->second);
}
};
以下是上面包装器的main(),如果我在包装器中没有使用可变参数模板,它可以正常工作: -
int main()
{
MappedTable Table(3) ;
std::string vid[]={"11", "21", "51", "41"};
std::string fare[]={"100", "400", "200", "4000"};
std::string vehicle[]={"bus", "car", "train", "aeroplane"};
int i=0;
for(i=0;i<4;i++)
{
Table.fnMapRow(i,vid[i],fare[i],vehicle[i]);
}
for(i=0;i<4;i++)
{
MAPPED_COLS mpCol=Table.fnGetRow(i);
std::cout<<"\n "<<i<<" "<<mpCol[0]<<" "<<mpCol[1]<<" "<<mpCol[2];
}
std::cout<<"\n";
return 0;
}
代码使用Boost 1.51.0编译,gcc 4.4使用std = c ++ 0x选项编译
有谁能告诉我,我错过了什么?
我愿意接受更好的想法,并且热衷于知道这个特定的例子即使效率不高也会如何运作。
下面的答案中提供了工作代码段(感谢Rost)。 如果任何人都可以建议一些更好的方法来将整个表存储到地图中,那就太棒了。
谢谢!
答案 0 :(得分:1)
您的可变参数模板函数语法看起来不正确。它应该是这样的:
template <typename... VarArgs>
void fnCols(const str& scCol2, const str& scCol3, const VarArgs&... args)
{
// Non-relevant code skipped
fnCols(scCol3, args...); // Recursive call with expanding arguments pack
}
与fnMapRow
类似的问题。
在模板成员函数定义之前也不需要template <str>
。
答案 1 :(得分:1)
我找到了问题的答案。以下是工作代码,如果有人将来需要它。
void fnCols() //termination version
{
}
template <typename... VarArgs>
void fnCols(const str& scCol2, const VarArgs&...args)
{
if(cols.size()>=iCols)
{
cols.erase (cols.begin(),cols.begin()+iCols);
}
cols.push_back(scCol2);
fnCols(args...);
}
template <typename... VarArgs>
void fnMapRow(int iCol1, const VarArgs&... args)
{
static const int iNumArgs = sizeof...(VarArgs);
if(iNumArgs==iCols)
{
fnCols(args...);
mapTable[iCol1]=MAPPED_COLS(cols);
}
}