I'm looking to store information from a data table with multiple rows and columns. Each column houses a differing type (int, double, std::string, etc), which would only be known at runtime.
Is a 2-d vector of boost::variant the best way, or are there better storing mechanisms to accomplish this?
From your question it's not clear what you're actually looking for. The answer depends on various factors:
Assuming you have different types per column, are the types the same for
all rows?
Are the types known at compile time or only at run-time?
In the simplest case of the types being known at compile time and being the same for all rows, why not simply use a custom class to represent a column or a std::tuple?
If the types are different between different columns, you must use a omnipotent type, such as boost::any.
This may also be the easiest solution should the types only be known at run-time.
Related
How could I compare two pointers to see if they are of the same type?
Say I have...
int * a;
char * b;
I want to know whether or not these two pointers differ in type.
Details:
I'm working on a lookup table (implemented as a 2D void pointer array) to store pointers to structs of various types. I want to use one insert function that compares the pointer type given to the types stored in the first row of the table. If they match I want to add the pointer to the table in that column.
Basically I want to be able to store each incoming type into its own column.
Alternative methods of accomplishing this are welcomed.
In this case, since you know the types before hand, it doesn't make much sense to check. You can just proceed knowing that they are different types.
However, assuming that perhaps the types may be dependent on some compile-time properties like template arguments, you could use std::is_same:
std::is_same<decltype(a), decltype(b)>::value
This will be true if they are the same type and false otherwise.
Question 1:
I'm using C++ 11, and I'm learning. I realize I can do this with two pairs:
pair<pair<<#class _T1#>, <#class _T2#>>, <#class _T3#>>
Is that the best way?
Question 2:
If I don't need different types, so same type for two items, is it a waste to use pair, what should I use then? For three items? (again same type)
Use a std::tuple:
std::tuple<_T1, _T2, _T3>
Note that std::tuples support an arbitrary amount of types stored in them. Also, to access the elements, you can't do the nice pair.first/pair.second, you have to use the syntax std::get<n>(tuple), where n is the element you want to retrieve.
Our task is to read information about table schema from a file, implement that table in c/c++ and then successfully run some "select" queries on it. The table schema file may have contents like this,
Tablename- Student
"ID","int(11)","NO","PRIMARY","0","".
Now, my question is what data structures would be appropriate for the task. The problem is that I do not know the number of columns a table might have, neither as to what might the name of those columns be nor any idea about their data types. For example, a table might have just one column of type int, another might have 15 columns of varying data types. Infact, I don't even know the number of tables whose description the schema file might have.
One way I thought of was to have a set number of say, 20 vectors (assuming that the upper limit of the columns in a table is 20), name those vectors 1stvector, 2ndvector and so on, map the name of the columns to the vectors, and then use them accordingly. But it seems the code for it would be a mess with all those if/else statements or switch case statements (for the mapping).
While googling/stack-overflowing, I learned that you can't describe a class at runtime otherwise the problem might have been easier to solve.
Any help is appreciated.
Thanks.
As a C++ data structure, you could try a std::vector< std::vector<boost::any> >. A vector is part of the Standard Library and allows dynamic rescaling of the number of elements. A vector of vectors would imply an arbitrary number of rows with an arbitray number of columns. Boost.Any is not part of the Standard Library but widely available and allows storing arbitrary types.
I am not aware of any good C++ library to do SQL queries on that data structure. You might need to write your own. E.g. the SQL commands select and where would correspond to the STL algorithm std::find_if with an appropriate predicate passed as a function object.
To deal with the lack of knowledge about the data column types you almost have to store the raw input (i.e. strings which suggests std:string) and coerce the interpretation as needed later on.
This also has the advantage that the column names can be stored in the same type.
If you realy want to determine the column type you'll need to speculatively parse each column of input to see what it could be and make decisions on that basis.
Either way if the input could contain a column that has the column separation symbol in it (say a string including a space in otherwise white space separated data) you will have to know the quoting convention of the input and write a parses of some kind to work on the data (sucking whole lines in with getline is your friend here). Your input appears to be comma separated with double quote deliminated strings.
I suggest using std::vector to hold all the table creation statements. After all the creation statements are read in, you can construct your table.
The problem to overcome is the plethora of column types. All the C++ containers like to have a uniform type, such as std::vector<std::string>. You will have different column types.
One solution is to have your data types descend from a single base. That would allow you to have std::vector<Base *> for each row of the table, where the pointers can point to fields of different {child} types.
I'll leave the rest up to the OP to figure out.
I have a situation where I want to create an STL Vector as either a vector<float> or vector<complex<float> >. The program will determine the data format at run-time based on an input.
This however does not seem to be possible without a ton of if/else statements. This is what I'm trying to do. Obviously this does not work b/c the typedef is local to the if/else.
if (INPUT_IS_REAL)
typedef TYPE float;
else
typedef TYPE complex<float>;
vector v1<TYPE>;
vector v2<TYPE>;
.....
Possible solution:
if (INPUT_IS_REAL)
code_path<float>();
else
code_path<complex<float>>();
Types are defined at compile time. You can't change types during execution. To handle two different data types you need two different pieces of code; you decide which to use when you know what input you're dealing with.
I am quite new to C++ but am familiar with a few other languages.
I would like to use a data type similar to a Java ArrayList, an Objective-c NSMutableArray or a Python array, but in C++. The characteristics I am looking for are the possibility to initialize the array without a capacity (thus to be able to add items gradually), and the capability to store multiple datatypes in one array.
To give you details of what I want it for is to read data from different tables of a mysql db, without knowing the number of fields in the table, and being able to move this data around. My ideal data type would allow me to store something like this:
idealArray = [Bool error,[string array],[string array]];
where the string arrays may have different sizes, from 1 to 20 in size (relatively small).
I don't know if this is possible in C++, any help appreciated, or links towards good ressources.
Thanks
The standard dynamically sized array in C++ is std::vector<>. Homogeneous containers doesn't exist unless you introduce indirection, for this you can use either boost::variant or boost::any depending on your needs.
You may use structure or class to store (named) multiple data types together, such as:
class Record
{
bool _error;
vector<string> _v1;
vector<string> _v2;
};
vector<Record> vec;
or std::tuple to store (unnamed) multiple data types, e.g.
vector<tuple<bool, vector<string>, vector<string> > > vec;
I would suggest using a std::vector from the STL. However, note that C++ does not have a container that can contain multiple data types. There are multiple ways to simulate this behaviour though:
Derive all the "types" that you want to store from a certain "Base_type". Then store the items in the vector as std::vector<Base_type*>, but then you would need to know which item is where and the type to (dynamic)cast to, if the "types" are totally different.
Use something like std::vector<boost::any> from the boost library (but noticing that you are new to C++, that might be overkill).
In fact, the question you need to ask is, why do you want to store unrelated "types" in an "array" in the first place? and if they are related, then "how"? this will guide you in desgining a decent "Base_type" for the "types".
And finally, in short, C++ does not have homogenous array-like structures that can contain unrelated data types.
You could try to use an std::vector<boost::any> (documentation here).