So I've made a class, one of it's function returns a struct vector, like so:
vector<highscore::players> highscore::returnL(){
load();
return list;
}
So list is basically,
struct players {
string name;
int score;
};
vectors<players> list;
In my source cpp, I tried to capture this vector, so I made another struct and struct vector.
Source.cpp:
struct players1 {
string name;
int score;
};
vector<players1> highscorelist;
Then I tried to
highscore high; //class' name is highscore
highscorelist = high.returnL();
But I get the error message:
No operator "=" matches these operands
" operand types are std::vector<players1, std::allocator<players1>> = std::vector<highscore::players, std::allocator<highscore::players>> "
Is it not possible to do it this way?
I honestly don't know what to search for so this might have been answered before, apologize if that's the case.
You could use reinterpret_cast, but that's not a good solution. Why don't you use highscore::player?
std::vector<highscore::player> highscoreList;
highscoreList = high.returnL(); // ok
highscore::player and player1 are different types, even though they have the same variables and probably even the same memory layout. You cannot just interchange types like that. Also, if you change one of those types, you have to change the other, which is just a maintenance nightmare if it were possible.
If you can, you could also use auto:
auto highscoreList = high.returnL();
Related
I'm playing a bit with the C++ syntax to figure out a generalized way to keep track of an offset within a class, sort of like offsetof, but in a type-safe way and without #defines
I know that a template class can be template-parametrized with fields, besides types and constants. So I came out with this prototype:
#include <iostream>
template <typename class_type, typename field_type>
struct offsetter
{
offsetter(const char* name, field_type class_type::*field)
: name(name)
{
fprintf(stderr, "%zu\n", field);
}
const char* const name;
};
struct some_struct
{
float avg;
int min;
int max;
struct internal
{
unsigned flag;
int x;
} test;
char* name;
};
int main()
{
offsetter<some_struct, float>("%h", &some_struct::avg);
offsetter<some_struct, int>("%h", &some_struct::min);
offsetter<some_struct, char*>("%h", &some_struct::name);
offsetter<some_struct, some_struct::internal>("x", &some_struct::test);
return 0;
}
This code is actually able to print the field offset, but I'm not really sure on what I'm doing here. Indeed it feels utterly wrong to reference field without referring to an instance (foo.*field).
But it does the job: it prints the offset. My guess is that I'm hitting on some loophole though, since for instance I can't assign size_t offset = field.
I figured out I probably want something like this:
size_t offset = (&(std::declval<class_type>().*field) - &(std::declval<class_type>()))
Which however wont' work as I can't take the address of an xvalue:
taking address of xvalue (rvalue reference)
Is there any way to do this?
AFAIK there isn't a standard way of doing this. Even the standard offsetof is defined only for standard layout types.
What you are doing is UB. You are using the wrong specifier zu. There isn't much you can do with a member pointer. You can't even do pointer arithmetics on them, you can't convert to char* nor to an integer type.
Also if your assumption is that a member pointer is just an integer representing the offset from the beginning of the structure that is false, not only in theory, but also in practice. Having multiple inheritance and virtual inheritance made sure of that.
Im wondering what I've done wrong in my code that is throwing the error.
(Note that due to external restrictions the use of -> is not allowed and brackets[] are not allowed anywhere except during array declaration)
Here are my two structs:
struct RentalCar
{
char make[10];
char model[10];
int year;
float price;
bool available;
};
struct Agency
{
char name[10];
int zipcode;
RentalCar inventory[5];
RentalCar* myCar = inventory;
};
Later in my code I have the following
Agency myAgencies[3];
Agency* myPointer = myAgencies;
I later try to reference the following when I get my error
inFile>>(*myPointer).(*myCar).make;
Due to external conditions, I'm not allowed to use the following fix:
inFile>>(*myPointer).inventory[0].make;
Any help is appreciated!
Your pointer dereferencing syntax isn't quite right. Perhaps the easiest way to fix this is by rewriting the
(*myPointer).(*myCar).make
using the arrow operator:
myPointer->myCar->make
If you cannot use -> then what what you can use is drop using the pointers and use the arrays themselves.
inFile>>(*myPointer).(*myCar).make;
Becomes
inFile >> myAgencies[0].inventory[0].make;
I have enable to the user choosing the type of data he wants to use, for example if he wants to use long or double etc.
I would like to declare first the name of the variable then set its type. Is it possible in C++?
If I understood your question correctly, you want to do this:
declare variable;
// in the program:
variable = (int) anotherVariable;
Short answer:
No
Long answer:
a void * does exactly this, it needs to be explicitly converted to a different type before dereferencing. But this is not possible on variables that are not void *s.
void *variable = NULL;
int someIntVariable = 100;
int *someIntPointer = NULL;
variable = &someIntVariable;
someIntPointer = (int *)variable;
.. // but this seems unncessary.
Have a look at boost::variant, or, if you need only PODs, union. However keep in mind that this complicates many things.
enum VariantType {
USER_INT, USER_DOUBLE
};
union Variant {
int i;
double d;
}
int main() {
VariantType type;
Variant data;
type = getUserDataType();
switch(type) {
case USER_INT:
data.i = 42;
break;
case USER_DOUBLE:
data.d = 42.0;
break;
default:
break;
}
...or use some ready Variant implmementation.
Look into using VARIANT (if you're on Windows) or something similar on other platforms. The point of VARIANT is that it's a union that is capable of storing all kinds of data types but only 1 particular type at a given time. This way you can define a new generic variable type (VARIANT) ahead of time and then adapt its internal type at run-time, depending on user choice.
Using something like VARIANT comes at a price, though, since every operation that you do on it will have to check if the operation is correct for the current underlying type. VARIANT also uses more memory since the union has its own overhead (see the definition for details).
You may want to wrap variant operations in a class to simplify its usage. The nice thing about VARIANT as opposed to void* is that it gives you a lot more type safety and the code becomes a lot more readable.
Edit: as another answer pointed out, boos::variant is for this purpose.
Before i start i will divide the problem into two parties:
PART 1 :
In c++ to get type of data we can use typeid but it's give you the data as const char* ,and i want it to return the type of the data.
Example:
int data = 20 ;
float data2 = 3.14 ;
char *data3 = "hello world" ;
std::cout<< typeid(data).nam() << endl << endl ;
std::cout<< typeid(data2).nam() << endl << endl ;
std::cout<< typeid(data3).nam() << endl << endl ;
Now i have a function that get data from void* , and convert it to another type :
template <typename t >
void print (void *data )
{
boost::any _t = static_cast<t> (data);
cout << boost::any_cast<t> (_t) << endl << endl;
}
Now this works fine if you know your data type:
Example:
void *mydata = alloca(size_object) ;
void some_function_store_int_data_in_voidpointer( &mydata)
print <int> (mydata); // it's ok .
But this is impractical when you have lots of different datatypes, like this:
void somefunction(args &a , void *dest )
{
/*code returnd data */
}
enum args
{
_INT_ ,
_FLOAT_ ,
_CHARPOINTER_ ,
};
vector <void *test> myvector ;
myvector.resize (3) ;
void somefunction(_INT_ , myvector.at(0) ) ; // store int in void*
void somefunction(CHARPOINTER , myvector.at(0) ) ;// store char* in void*
void somefunction(_FLOAT_ , myvector.at(0) ) ;// store float in void*
print <int> (myvector.at(0));
print <char*> (myvector.at(1));
print <float> (myvector.at(2));
1 - If i use something like this
print <typeid(myvector.at(2))> (myvector.at(2));
i get an error because my data is float and I make it const char*
2 - Perhaps I can pass the type of every value if I have few data. This is OK. But what if I have 100 values from different types!
I am looking for something like: typeid but it' return the type not `const char*.
PART 2
because I have avector I will use a for_each algorithm like this:
for_each ( myvector.begin() , myvector.end() , print</*what i should pass her int , float ,char* ...or what , */>);
In the previous code I can pass only one type to the function so the data from the same type will print. Else the data that are not the same type will print, but completely wrong (Strange format).
So if I pass char* the int data will print completely wrong.
How can I do this differently?
How can I do this differently?
If your intention is to use same function for printing different data formats, then you can do it like this:
#include <iostream>
#include <algorithm>
#include <vector>
template <typename T> class Callback{
public:
void operator()(const T& value) const{
std::cout << value << std::endl;
}
};
template <typename T> Callback<typename T::value_type> makeCallback(const T&){
return Callback<T::value_type>();
}
int main(int argc, char** argv){
std::vector<int> ints(20);
std::vector<float> floats(20);
std::fill(ints.begin(), ints.end(), 0);
std::fill(floats.begin(), floats.end(), 0.0f);
std::for_each(ints.begin(), ints.end(), makeCallback(ints));
std::for_each(ints.begin(), ints.end(), makeCallback(floats));
return 0;
}
However, if you want to store several different data types in same std::vector, then you need "variant" types (like boost::variant, QVariant or similar), and there's no way around it.
I am looking for something like: typeid but it' return the type not `const char*.
In C++ "type" exists only at compilation stage, so you cannot return it, because it no longer exists once program has been compiled. There's no "type", so you can't return it.
So to get a "type" from object you need to implement some kind of "variant" type that can hold any object along with its type information, and pass that "variant" type around. One example of such system is QVariant in Qt 4.
AFAIK implementation of variant type goes like this: there is some kind of table for every type variant supports, you register all types variant class must support in that table. Table provides functions for creating type, destroying type, (de)serializing type, and possibly information about amount of memory required by one object of the type. The table can contain optional information you want, and you can convert entire registration procedure into macros+template combo. As you can see, this is not something that is done automatically by compiler, but something that involves plenty of hassle and must be taken care of by programmer. Also, things get much more fun if program must be able to take types developed externally (in plugins, etc).
As a result of language restrictions, the better idea would be to avoid situations when you need to "return type" when possible - variant systems aren't exactly difficult, but they aren't much fun either, due to all necessary sanity checks and conversions. Example problem: if you pass a string in variant type to a function that is supposed to take a float, should this function attempt to convert string to float? If conversion fails, should it crash/throw exception, or assume that variable has default value? If there's default value for failed conversions, what should it be and how should it be passed? And so on. This isn't a rocket science, but it is quite annoying to deal with.
For example, you could get rid of "void*" (if function takes pointer as an argument, then I would assume that poitner can be NULL/0. So "void*" arguments aren't exactly a good idea). arguments in your functions and use templates to make compiler generate code your want for types you actually use in your program. If templates are not an option, then you need some kind of "variant" type (preferably developed by somebody else), ... or you could switch to another language that provides type information you need. You don't have to use C++, any tool that does the job will do. Relying on RTTI also isn't a perfect solution, becuase if you manage to pass a pointer to something that does NOT contain type information, you'll get a non-standard exception (__non_rtti_object).
If you have a limited list of types you want to support, use boost::variant<int, float, const char*, ...> instead of boost::any (or void*). Then you can define a visitor to call the correct instantiation of the print function.
#include <boost/variant.hpp>
#include <boost/foreach.hpp>
#include <vector>
#include <algorithm>
#include <iostream>
template <class T>
void print(T t)
{
std::cout << t << '\n';
}
struct print_visitor: boost::static_visitor<void>
{
template <class T>
void operator()(T t) const { print(t); }
};
int main()
{
typedef boost::variant<int, double, const char*> Variant;
std::vector<Variant> vec;
vec.push_back(13);
vec.push_back(3.14);
vec.push_back("Hello world");
BOOST_FOREACH(const Variant& v, vec) {
boost::apply_visitor(print_visitor(), v);
}
}
With a void* or a boost::any, I don't think you can do better than use a long if-chain to test all supported types.
C++ is a statically typed language, thus types only really exist in a meaningful way at the compile time, not at runtime. At runtime the best C++ can give you is RTTI which provides you with things like dynamic_cast<> and typeid(), which are however limited to giving you information along the inheritance hierarchy only, i.e. if you have
class Base
class DerivedA : public Base
class DerivedB : public Base
and you have a Base* or Base& you can find out if it's a Base, a DerivedA or a DerivedB. However in your case you only have a void*, which is completely outside of any inheritance hierarchy and thus has no type information associated with it. Thus all typeid() will tell you is that you have a void*, it won't tell you whatever type might hide behind it.
Furthermore a construct like:
print <typeid(myvector.at(2))> (myvector.at(2));
wouldn't work in C++ either, as the type for a template also needs to be known at compile time. Here however the type of .at(2) would only be known at runtime.
So to solve your problem you have to do the type handling yourself. Meaning you have to store the type along with the object you want to store, which would look something like this:
struct Value
{
enum { kInt, kString } type;
union {
int vInt;
char* vChar;
} value;
};
[...]
Value v;
v.type = Value::kInt;
v.value.vInt = 5;
switch(v.type)
{
case Value::kInt:
// do int specific stuff
break;
case Value::kString:
// do string specific stuff
break;
}
The boost::variant<> class that visitor mentioned provides basically the above in a nicely packaged way.
Another thing worth to mention is decltype, decltype is new in C++11 standard and allows you to get the actual type of an object and thus you can write code like:
int a;
decltype(a) b;
Where b gets the same type as a, i.e. int. This sounds exactly like what you want, but it is not, decltype() has the same restrictions as before. It can only work when the type is already known at compile time, it can't do anything with types only known at runtime. Thus it will not work in your situation and is only really useful when doing some more complex template programming.
Long story short, use boost::variant<> or write yourself a class that works in a similar way.
PART 1: I'm not quite sure I fully understand your query, but have you looked at the header file <typeinfo>? struct type_info may be what you're looking for.
I want to be able to do the following:
I have an array of strings that contain data types:
string DataTypeValues[20] = {"char", "unsigned char", "short", "int"};
Then later, I would like to create a variable of one of the data types at runtime. I won't know at compile time what the correct data type should be.
So for example, if at runtime I determined a variable x needed to be of type int:
DataTypeValues[3] x = 100;
Obviously this won't work, so how could I do something like this?
The simple answer is that you can't - types need to be known at compile time in C++. You can do something like it using things like boost::any or unions, but it won't be pretty.
you would have to use unions to achieve something like that, but handling unions is a very difficile matter, so you should choose a container class which wraps the union logic behind an interface like Boost.Variant or Qts QVariant
You can't. This kind of run-time metaprogramming is not supported in C++.
Everyone saying you can't do this in C++ is missing one obvious solution. This is where you could use a base class, you need to define the commonly used interface there, and then all the derived classes are whatever types you need. Put it in a smart pointer appropriate for a container and there you go. You may have to use dynamic type inference if you can't put enough of the interface in the base class, which is always frowned upon because it's ugly, but it's there for a reason. And dynamically allocating your types probably isn't the most efficient thing, but as always, it depends on what you're using it for.
I think you are really looking for a dynamically-typed language. Embed an interpreter if you must stick with C++!
Or you could implement something akin to the component model using interfaces to work with wrapped data. Start with the cosmic base class - IObject, then implement interfaces for IInteger, IDouble, IString, etc. The objects themselves would then get created by a factory.
Or you could just use void buffers with a factory... That's the age-old way of avoiding static typing in C/C++ (without the use of inheritance-based polymorphism). Then sprinkle in generous amounts of reinterpret_cast.
The closest you can get is with templates:
template<int i> class Data { };
template<> class Data<0> { typedef char type; }
template<> class Data<1> { typedef unsigned char type; }
template<> class Data<2 { typedef short type; }
template<> class Data<3> { typedef int type; }
Data<3>::Type x;
If you need something a lot more complex, Boost has a C++-Python bridge.
use union and make your own dynamic class.
the pseudocode like:
union all{
char c;
unsigned char uc;
short s;
int i;
};
class dynamic{
public:
char Type;
all x;
template <class T>
dynamic(T y){
int Int;
char Char;
unsigned char Uchar;
short Short;
if (typeof(y) == typeof(Char)){
Type = 1;
}else if (typeof(y) == typeof(Uchar)) {
Type = 2;
}else if (typeof(y) == typeof(Short)) {
Type = 3;
}else{
Type = 4;
}
switch (Type) {
case 1: x.c = y; break;
case 2: x.uc = y; break;
case 3: x.s = y; break ;
case 4: x.i = y; break ;
}
}
auto get() {
switch(Type) {
case 1: return x.c;
case 2: return x.uc;
case 3: return x.s;
case 4: retuen x.i;
}
}
//also make the operators function you like to use
} ;
however you should avoid using the dynamic type as possible as you can because it is memory inefficient
(in this example, each object of dynamic will takes 5 bytes)
it will also slow down your code (a bit).if in your example you want to use dynamic type of number variable only to reduce memory usage, you should forget about dynamic and just use the integer as the type (where integer can contain all of char, unsigned char, and short at once).
but if you want to use it because you need a dynamic type between something really different (example between an int and a string or a custom object), then it will be one of your option.
The only thing you can do is manually loop through the types and compare each individual one. There's also the potential to use a factory object here - but that would involve the heap.
Visual Basic's 'Variant' data type is what you are talking about. It can hold anything, primary data types, arrays, objects etc.
"The Collection class in OLE Automation can store items of different data types. Since the data type of these items cannot be known at compile time, the methods to add items to and retrieve items from a collection use variants. If in Visual Basic the For Each construct is used, the iterator variable must be of object type, or a variant." -- from http://en.wikipedia.org/wiki/Variant_type
The above page gives some insights on how variants are used and it shows how OLE is used in C++ for dealing with variants.
In your simple example, there would be little benefit in not simply using the widest type in the list as a generic container and casting to the smaller types when necessary (or even relying on implicit casts).
You could get elaborate with unions, classes, polymorphism, RTTI, Boost variants etc, but merely for a list of different width integers it is hardly worth the effort.
It seems to me you have a perceived problem for which you have invented an impractical solution for which you are now asking for help. You'd probably be far better off describing your original problem rather than making your solution the problem!
Also, don't forget that all the functions that must operate on this mysterious data type. Most functions are designed to use only one type, such as addition. The functions are overloaded to handle additional types.
How do you know at run-time what the variable type is?
The only way that come to mind now is the old C style where pointer to void was used like:
void *unkown;
Leter on you can assign any object to it like below:
unkown = (void *)new int(4);
If you know the type in the runtime then you may run specified function on such variable like below:
if(type==0) { // int
printf("%d\n", * ((int*)unkown) );
} else {
// other type
}
This way (casting void*) is used for example when malloc [, etc.] function is used.
I'm not saying it is a good practise when c++ is now much more developed.
Still agree with persons that saying it is not the best solution for your problem. But maybe after some redesign you may find it helpful.
You may find also interesting auto type since C++11.
http://en.cppreference.com/w/cpp/language/auto
I guess this reply would be a few years late. But for people who might happen to view this thread, a possible solution for this would be using variable templates. For example:
template<typename T>
T var;
template<typename T>
T arr[10];
int main() {
int temp;
var<int> = 2;
cout << var<int> << ' '; // this would output 2
var<char> = 'a';
cout << var<int> << ' '; // var<int> value would be a space character
cout << var<char> << ' '; // this would output 'a'
for(int i = 0; i < 10; i++) {
switch(i % 2) {
case 0:
arr<int>[i] = ++temp;
break;
case 1:
arr<char>[i] = 'a' + ++temp;
break;
}
cout << endl;
for(int i = 0; i < 10; i++) {
switch(i % 2) {
case 0:
cout << arr<int>[i] << ' ';
break;
case 1:
cout << arr<char>[i] << ' ';
break;
}
}
return 0;
}
The only problem with this, is that you would need to know the variable type of what is currently within the variable(e.g. storing in an integer array what the variable's "id"(the id you would give it), for a specific type). If you do not know or do not have a condition to know what is inside a specific variable or array location, I do not suggest using this.
I try to post it in here, but I had format error. I decided to put a link.
Any way you can use (long long) to store addresses because size of address is 8 and size of (long long) also is 8 then it can hold an address.
https://www.flatech.com.au/learning-material/programming/c/object-pointers-to-any-type