┃Name|Age|..┃
┠────┼───┼──┨
┃John│025│..┃
┃Carl│033│..┃
┃....│...│..┃
在这种情况下,我指的是一个具有固定列大小和可变大小的未排序行的表,可以通过id进行寻址。
C ++ 11(或更早版本)中是否有可以表示此类数据的数据结构?
我想到了几种欺骗这种结构的方法,但没有一种方法是完美的。
std::vector
std::vector<std::string> name;
std::vector<unsigned int> age;
// Write
name.push_back("John");
age.push_back(25);
// Read
std::cout << "The first entry is (" << name[0] << " | " << age[0] << ")\n";
但是,定义一个包含许多列的表需要大量标记,并且通过在每个push_back
上调用std::vector
来写入它是非常糟糕的。
std::vector
std::tuple
(在这种情况下std::pair
就够了)
std::vector<std::tuple<std::string, unsigned int>> table;
// Write
table.push_back(std::make_tuple("John", 25));
// Read 1
std::string name;
unsigned int age;
std::tie(name, age) = table[0];
std::cout << "The first entry is (" << name << " | " << age << ")\n";
// Read 2
enum
{
NAME = 0,
AGE
}
std::cout << "The first entry is (" << std::get<NAME>(table[0]) << " | "
<< std::get<AGE>(table[0]) << ")\n";
(对不起,如果我在这里搞砸了一些东西;我从昨天开始就知道std::tuple
的存在)
这很好,但是从它读取需要大量标记,这次,当你必须定义你想要放入值的新变量时。你可以只做std::tie
到任何变量你需要值,但这变得不可读。第二种方法几乎是完美的,但使用隐式枚举并不是我想在C ++ 11中做的事情。
std::vector
std::array
enum
{
NAME = 0,
AGE
}
std::vector<std::array<std::string, 2> table;
// Write
table.push_back({"John", "25"});
// Read
std::cout << "The first entry is (" << table[0][NAME] << " | " << table[0][AGE] << ")\n";
这也很不错,但它遇到了与2.2相同的问题。此外,这仅允许std::string
值。作为交换,它提供了更短更好的语法。
答案 0 :(得分:2)
我建议std::vector<Record>
保存您的记录。
使用std::map<key, vector_index>
作为记录的索引。这将使您能够通过不同的搜索条件访问记录,而无需始终对矢量进行排序。
答案 1 :(得分:1)
您要考虑的一件事是使用std::map
某种关联数组,即std::unordered_map
或item["Name"]
item["Age"]
。
这将允许您使用数据库列名检查向量(或其他顺序容器)中的给定项目
boost::any
等等。显然,您必须使用变体或{{1}}之类的值作为值。
如果您希望使用C ++与数据库通信,并且在编译时知道列的类型(从您的建议中看来),可能值得考虑直接从您生成具有适当结构的代码的方法。数据库scehema。围绕此主题有几个问题here和here。如果db值为null会怎么样?
答案 2 :(得分:0)
#-------------------------------------------
#Try with this piece of code based on <map>
#-------------------------------------------
#include <iostream>
#include <map>
using namespace std;
//---
class myBook
{
public:
string ISBN;
string Title;
int Pages;
myBook();
myBook(const myBook &);
~myBook(){};
myBook &operator=(const myBook &pTr);
int operator==(const myBook &pTr) const;
int operator<(const myBook &pTr) const;
};
myBook::myBook()
{
ISBN = "";
Title = "";
Pages = 0;
}
myBook::myBook(const myBook ©in)
{
ISBN = copyin.ISBN;
Title = copyin.Title;
Pages = copyin.Pages;
}
ostream &operator<<(ostream &output, const myBook &myBook)
{
output << myBook.ISBN << ':' << myBook.Title << ':' << myBook.Pages << std::endl;
return(output);
}
myBook& myBook::operator=(const myBook &pTr)
{
this->ISBN = pTr.ISBN;
this->Title = pTr.Title;
this->Pages = pTr.Pages;
return(*this);
}
int myBook::operator==(const myBook &pTr) const
{
if( this->ISBN != pTr.ISBN) return(0);
if( this->Title != pTr.Title) return(0);
if( this->Pages != pTr.Pages) return(0);
return(1);
}
//---------------------------
main()
{
map<string, myBook> BooksLibrary;
myBook book1;
//---
book1.ISBN="1243954-23";
book1.Title="Autobiography by Ben Franklin";
book1.Pages=432;
BooksLibrary["0001"] = book1;
//---
book1.ISBN="555-USA991";
book1.Title="I Robot by Isac Asimov";
book1.Pages=323;
BooksLibrary["0002"] = book1;
//---
for( map<string, myBook>::iterator ii=BooksLibrary.begin(); ii!=BooksLibrary.end(); ii++)
{
std::cout << (*ii).first << "|" << (*ii).second << endl;
}
//---
return(0);
}