C++ Parameters Structure supporting strings and integers? - c++

How can I do this way easier:
struct Parameters {
public:
int Parameter1;
std::string Parameter1;
int Parameter2;
std::string Parameter2;
}
Isn't there "var" in C++ like in .NET ? I need parameters to be able to be integers and strings.

You have the key word 'auto' in C++ but it's on C++0x and C++1x, it's the compiler which will decide the type and it can't change after the compilation.
You're probably looking for something like boost::variant: http://www.boost.org/doc/libs/1_56_0/doc/html/variant.html

You can use Union, but you will still need to know at compile time what type you are assigning. You can sort of hide this by using templates with implicit typing to assign values, but you will still have to know the appropriate type when reading the value. Not sure how useful that would be though.
You could also use polymorphism and your own (template) wrapper class in place of the built in types.

I suggest you factor out the common code and set up to use a factory.
Use of a Factory
The problem is that you don't know the type of the parameter until you parse the string. The best method is to keep everything as a string or create a Factory and use a base class. For more research, see "c++ factory design pattern example".
struct Base_Parameter
{
std::string& parameter_as_string;
virtual void extract_parameter(const std::string& parameter_string) = 0;
};
struct Int_Parameter : public Base_Parameter
{
int parameter_value;
void extract_parameter(const std::string& parameter_string)
{
std::istringstream param_stream(parameter_string);
param_stream >> parameter_value;
}
}
Your parameter "list" would be either a container of pointers to the base class (if the types are unknown) or you could have a container of the descendent struct:
struct Parameter_Container
{
std::vector<Int_Parameter> parameters;
};
As for the factory, the factory would be an object that could create parameter objects based on some criteria. It would return a pointer to the base class.
Note: Unless you are on a tightly constrained platform, such as an embedded system, don't worry about overlapping memory locations to save room.

Related

Collections holding different Types Simultaneously

Traditionally, I've programmed in c++ and Java, and I'm now beginning to learn ruby.
My question then is, how do languages like ruby internally implement their array and hash data structures in such a way that they can hold any type at the same time? I know that in Java, the fact that every class is derived from object, could be one way to implement this, but I was wondering if there was another way. For example, in c++, if I wanted to implement a dynamic array that could simultaneously hold multiple types of values (of no relation), how could I do this?
To clarify, I'm not referring to generic programming or templates, as those simply create a new collection interface for a type. I'm referring to a structure such as this:
array = [1, "hello", someClass];
Most of them do roughly the same as you'd get in C++ by creating a vector (or list, deque, etc.) of boost::any, or something similar.
That is to say, they basically attach some tag to each type of object as it's stored in memory. When they store an object, they store the tag. When they read an object, they look at the tag to figure out what kind of object that is. Of course, they also handle most of this internally, so you don't have to write the code to figure out what kind of object you've just retrieved from the collection.
In case it's not clear: the "tag" is just a unique number assigned to each type. If the system you're dealing with has primitive types, it'll normally pre-assign a type number to each of them. Likewise, each class you create gets a unique number assigned to it.
To do that in C++, you'd normally create a central registry of tags. When you register a type, you receive a unique number back that you use to tag objects of that type. When a language supports this directly, it automates the process of registering types and choosing a unique tag for each.
Although this is probably the most common method of implementing such things, it's definitely not the only one. Just for example, it's also possible to designate specific ranges of storage for particular types. When you allocate an object of a given type, it's always allocated from that type's address range. When you create a collection of "objects", you're really not storing the objects themselves, but instead storing something that contains the address of the object. Since objects are segregated by address you can figure out the type of the object based on the value of the pointer.
In the MRI interpreter, a ruby value is stored as a pointer type which points to a data structure storing the class of the value and any data associated with the value. Since pointers are always the same size, (sizeof(unsigned long) usually), it is possible. To answer your question about C++, it is impossible in C++ to determine the class of an object given it's location in memory, so it wouldn't be possible unless you had something like this:
enum object_class { STRING, ARRAY, MAP, etc... };
struct TaggedObject {
enum object_class klass;
void *value;
}
and passed around TaggedObject * values. That is pretty much what ruby does internally.
There are many ways to do that :-
You can define a common interface for all the elements and make a container of those. For example:
class Common { /* ... */ }; // the common interface.
You can use container of void* :-
vector<void*> common; // this would rather be too low level.
// you have to use cast very much.
And then the best approach I think is using an Any class, such as Boost::Any :-
vector<boost::any> v;
You're looking for something called type erasure. The simplest way to do this in C++ is with boost::any:
std::vector<boost::any> stuff;
stuff.push_back(1);
stuff.push_back(std::string("hello"));
stuff.push_back(someClass);
Of course with any, you're extremely limited in what you can do with your stuff since you have to personally remember everything you put into it.
A more common use-case of heterogeneous containers might be a series of callbacks. The standard class std::function<R(Args...)> is, in fact, a type-erased functor:
void foo() { .. }
struct SomeClass {
void operator()() { .. }
};
std::vector<std::function<void()>> callbacks;
callbacks.push_back(foo);
callbacks.push_back(SomeClass{});
callbacks.push_back([]{ .. });
Here, we're adding three objects of different types (a void(*)(), a SomeClass, and some lambda) to the same container - which we do by erasing the type. So we can still do:
for (auto& func : callbacks) {
func();
}
And that will do the right thing in each of the three objects... no virtuals needed!
Others have explained ways you can do this in C++.
There are various ways to solve this problem. To answer your question about how does languages such as Ruby solve this, without going into details of exactly how Ruby solves it, they use a structure that contains type information. For example, we could do that in C++ something like this:
enum TypeKind { None, Int, Float, String }; // May need a few more?
class TypeBase
{
protected:
TypeKind kind;
public:
TypeBase(TypeKind k) : kind(k) { }
virtual ~TypeBase() {};
TypeKind type() { return kind; }
};
class TypeInt : public TypeBase
{
private:
int value;
public:
TypeInt(int v) : value(v), TypeBase(Int) {}
};
class TypeFloat : public TypeBase
{
private:
double value;
public:
TypeFloat(double v) : value(v), TypeBase(Float) {}
};
class TypeString : public TypeBase
{
private:
std::string value;
public:
TypeString(std::string v) : value(v), TypeBase(String) {}
};
(To make it useful, we probably need some more methods for the TypeXxx class, but I don't feel like typing for another hour... ;) )
And then somewhere, it determines the type, e.g.
Token t = getNextToken();
TypeBase *ty;
if (t.type == IntegerToken)
{
ty = new(TypeInt(stoi(t.str));
}
else if (t.type == FloatToken)
{
ty = new(TypeFloat(stod(t.str));
}
else if (t.type == StringToken)
{
ty = new(TypeString(t.str));
}
Of course, we'd also need to deal with variables and various other scenarios, but the essence of it is that the language can keep track of (and sometimes mutate) the value that is stored.
Most languages in the general category where Ruby, PHP, Python, etc are, will have this sort of mechanism, and all variables are stored in some sort of indirect way. The above is just one possible solution, I can think of at least half a dozen other ways to do this, but they are variations on the theme of "store data together with type information".
(And by the way, boost::any also does something along the lines of the above, more or less....)
In Ruby, the answer is rather simple: that array doesn't contain values of different types, they are all of the same type. They are all objects.
Ruby is dynamically typed, the idea of an array that is statically constrained to only hold elements of the same type doesn't even make sense.
For a statically typed language, the question is, how much do you want it to be like Ruby? Do you want it to be actually dynamically typed? Then you need to implement a dynamic type in your language (if it doesn't already have one, like C♯’s dynamic).
Otherwise, if you want a statically typed heterogenous list, such a thing is usually called an HList. There's a very nice implementation for Scala in the Shapeless library, for example.

How to create user defined type template class object C++

I am struggling with allowing user to select data type template will be created as.
Since template type must be defined on compile, I must specify data type template will use eg(string,int, so on), but that means I cannot change it latter on, from lets say string to int even if my template supports it, because template class object was declared as string.
My class declaration below:
template <class T>
class MyHashTable
{
public:
string deleted="deleted";
unsigned short tableSize;
// array of vectors, hash table container
vector<T>* myTable;
vector<T>* deletionTable;
MyHashTable(unsigned short tableSize) : myTable(new vector<T>[tableSize]), deletionTable(new vector<T>[tableSize])
{
this->tableSize=tableSize;
}
object declaration outside class
MyHashTable <string>* myChainedTable=NULL ;
string tableType;
object initialization
if (myChainedTable)
{
delete myChainedTable;
myChainedTable=NULL;
}
getType();
if (!myChainedTable)
{
if (tableType=="string")
myChainedTable= new MyHashTable<string>(length);
if (tableType=="char")
MyHashTable<char> myChainedTable(length); // no difference with or without using new keyword
if (tableType=="double")
MyHashTable<double> myChainedTable(length);
if (tableType=="float")
MyHashTable<float> myChainedTable(length);
if (tableType=="int")
MyHashTable<int> myChainedTable(length);
cout<<tableType<<" table of size "<< length<<" created"<<endl;
I attempted passing class object to functions instead of having it as global variable, but couldnt get it work either.
What I really need is single template object that can have: int,string,char,double,float types, I have 3 functions that need to have access to template class object, and having 5 different objects and 200 lines of if statements for each situation sounds like worst possible solution.
I been stuck on this for a while and just cant figure out how to do it and any help will be appreciated.
void getType()
{
cout<<"Enter table type, types available: int, char, float, double, string.\n";
tableType=getInput();
while((tableType != "int")&&(tableType !="float")&&(tableType !="double")&&(tableType!="char")&&(tableType !="string"))
{
cout<<"Invalid type, please try again "<<endl;;
tableType=getInput();
}
}
Your question is at the boarder between templates and variants.
The template is compile time. So you have to choose at compile time the type you want for your object. Your conditional approach can't work (see comments to question).
On the other side, you seem to need a dynamic choice of type at runtime.
If you want to go on on template way: (edit based on comments)
You'd need to have all the templates inherit from a single polymorphic base class (one common interface with virtual functions). Example:
class MyHashBase // common base class for all templates
{
public:
virtual void addElement(void *ptrelem) = 0; // adding an element must be implemented by template. With void* since future template type unknown from base class
virtual void displayAll() = 0;
};
The templates would need then implement the virtual functions:
template <class T>
class MyHashTable : public MyHashBase
{
public:
unsigned short tableSize;
vector<T>* myTable; // I leave it as it is, but you could implement these as vector<T> instead of vector<T>*
vector<T>* deletionTable;
MyHashTable(unsigned short tableSize) : myTable(new vector<T>[tableSize]), deletionTable(new vector<T>[tableSize]), tableSize(tableSize)
{ }
void addElement(void* ptrelem)
{ myTable->push_back(*reinterpret_cast<T*>(ptrelem)); } // reinterpret the void* of the common interface as a T*
void displayAll()
{ copy(myTable->begin(), myTable->end(), ostream_iterator<T>(cout, "\n")); }
};
You could then have your myChainedTable be a pointer to the common base type, and intialise this pointer in the way you did with the string case (i.e. using new).
MyHashBase *myChainedTable = nullptr;
//...
if (tableType == "string")
myChainedTable = new MyHashTable<string>(length);
else if (tableType == "double")
myChainedTable = new MyHashTable<double>(length);
//...
You could then use the common API, for example if tableType is "double":
double d1 = 3.1415, d2 = 1.4142;
myChainedTable->addElement(&d1); // ATTENTION: you must ensure to provide pointer to the correct data type
myChainedTable->addElement(&d2);
myChainedTable->displayAll();
You'll certainly have a coupe of if required in the calling code, but you could reduce them to minimum by carefully designing the base class (for example, you could add a virtual clone function, to duplicate the data without need to know the type by the caller).
However, using a single signature for the common functions of the base class is cumbersome. To make the virtualisation possible you need to pass parameters through void* pointer which is not so nice and rather error prone.
Alternate way with variants
You could also use boost variants which are meant for managing objects with dynamic definition of types.
In this case you would not need template for your own data structure. You would create a MyHashTable with elements of type boost::variant< int, std::string, ... >.
You could then access to the right value of the object if you know its type (as in your myChainedTable) by using: boost::get<int> (element) (or boost::get<string>(), ...).
If you don't know the type on an element you could use the concept of "visitor" to chose automatically the appropriate function to exectue depending on the type.
Edit: alternate way with unions:
If you're not allowed to use variants another alternative could be use a union. I don't know the topic of you rassignment, but you have the choice whether you use a union to define the elements (like the variants, without templates) or to use a template type as you did, but define myChainedTable to be a union of pointers to the different template instantiations. But yes, it requires a lot of ifs...
Templates are resolved at compile time. Your container type is resolved at runtime. Templates are clearly not the solution here. The first thing that comes to my mind is a combination of boost::any and std::vector instead.

How to save a type of a pointer c++

Function1 can be called with any type T which will be converted to (void*) to be able to add to the list but with this I lose the original pointer type (I need t store tham in one linkedlist because I cannot create one for every possible type). So somehow I need to save the type of the pointer as well. I know that it cant be done using c++. Can anyone suggest an alternative solution?
class MyClass
{
template<class T>
void function1(T* arg1)
{
myList.add((void*)arg);
}
void function2()
{
for(int i = 0; i < myList.size(); i++)
{
myList.get(i);
//restore the original pointer type
}
}
STLinkedlist<void*> myList;
}
The usual way to handle these kinds of problems is by using a public interface, in C++ this is done through inheritance. This can be a drag, especially in constrained situations, where a full class/interface hierarchy would provide too much code/runtime overhead.
In comes Boost.Variant, which allows you to use the same object to store different types. If you need even more freedom, use Boost.Any. For a comparison, see e.g. here.
At the end of the day (or better: rather sooner than later), I'd try to do things differently so you don't have this problem. It may well be worth it in the end.
If you lost the type info by going void* it is just gone. You can not just restore it.
So you either must store extra information along with the pointer, then use branching code to cast it back, or rather drive design to avoid the loss.
Your case is pretty suspicious that you do not what you really want.
A more usual case is that you want a polymorphic collection. That doesn't store any kind of pointers but those belonging to the same hierarchy. Collection has Base* pointers, and you can use the objects through Base's interface, all calling the proper virtual function without programmer's interaction. And if you really need to cast to the original type you can do it via dynamic_cast safely. Or add some type info support in the base interface.
Function1 can be called with any type T which will be converted to (void*) to be able to add to the list but with this I lose the original pointer type (I need t store tham in one linkedlist because I cannot create one for every possible type).
You're having the XY problem. The solution is not to decay your pointers to void* and store type information.
You simply can create a type for every possible type - you create a template type. You need to define an abstract interface for your "type for every object", then define a template class implementing this interface, that is particularized by type. Finally, you create your custom-type instance on your type of pointer received and store them by base class pointer (where the base class is your interface definition).
All that said, you (normally) shouldn't need to implement this at all, because the functionality is already implemented in boost::any or boost::variant (you will have to choose one of them).
General
Take into consideration, that if you want to store different objects inside a std::vector<void *>, mostly likely your application has a bad design. In this case, I'd think, whether it is really necessary to do it (or how can it be done in another way), rather than searching for the solution, how to do it.
However, there are no fully evil things in C++ (nor in any other language), so if you are absolutely certain, that this is the only solution, here are three possible ways to solve your problem.
Option 1
If you store only pointers to simple types, store the original type along with the pointer by an enum value or simply a string.
enum DataType
{
intType,
floatType,
doubleType
};
std::vector<std::pair<void *, DataType>> myData;
Option 2
If you store mixed data (classes and simple types), wrap your data in some kind of class.
class BaseData
{
public:
virtual ~BaseData() { }
};
class IntData : public BaseData
{
public:
int myData;
};
std::vector<BaseData *> myData;
Later, you'll be able to check the type of your data using dynamic_cast.
Option 3
If you store only classes, store them simply as a pointer to their base class and dynamic_cast your way out.
You could use boost::any to store any type in your list instead of use void*. It's not exactly what you want but I don't think you can restore the type in run time (as Kerrek said, it's not Java).
class MyClass
{
template<class T>
void function1(T arg1)
{
myList.add(arg);
}
template<class T>
T get(int i)
{
return boost::any_cast<T>(myList.get(i));
}
STLinkedlist<boost::any> myList;
};

OOP - How should this be done?

I have a class that has the following variables/members:
First Name
Last Name
Age
Address
etc..
I want to create getter-methods for each of them that returns the values. This could become quite large depending on the class.
Is there a quicker or more object-oriented way that would allow me to do this just using one method? The only way I can think about is to have a method that takes a parameter of the name of the variable to be returned; however, the types for the method would change depending on if it was returning a string, int etc..
Does anyone have a solution?
Why do you need those values outside the class? If you have code that is not in Person that calls 4 or 5 Person GetWhatever() methods and glues the strings together, stuffs commas between them and so on, move that code into Person. Do that enough and no code outside Person needs to call your getters.
Some classes are logic-free, they just hold values, and they expect outside objects to do all the work. In C++, using a struct for that makes your intention clear. If you insist that code outside Person needs to arbitrarily access elements of Person, it's probably a struct, not a class. If you insist it's a class, prove it by adding some actual business logic to it.
No, there is no "better" way which is still object-oriented. You should define one public "getter" method for each private member variable which needs to be access outside the class. You should also define a setter method, if the variable is meant to be set from outside the class.
If you want easy to define setter/getter - make it on single member level. Make member template with setter/getter and define is as public element of your class:
template <class Type>
class Member {
public:
Member(const T& value = T()) : value(value) {}
void setValue(const Type& t) { value = t; }
T getValue() const { return value; }
private:
T value;
};
Use it in your class:
class Person {
public:
Member<std::string> firstName;
Member<std::string> lastName;
Member<std::string> address;
Member<unsigned> age;
};
And usage:
int main() {
Person one;
one.firstName.setValue("Joe");
one.age.setValue(33);
}
If your need some constraints (like range checking) then define some RangeCheckingMember template. If you need the members to be dependent on each others - then make relationship between them by pointers/references.
Consider making that parameter lookup using a template member function that takes a default value in a given type.
template<typename ValueType>
const ValueType& get(const KeyType& key, const ValueType& default value) {
...
};
You still have to enumerate (or otherwise list) a KeyType of all your values (or use std::string which might be fine in larger cases) and work back and forth with your storage on the ValueType.
So, this doesn't really help you much until you decide you need arbitrarily large or completely dynamic values. At this point, you need to implement a map which can hold any type which requires either hideous unions or a template wrapper derived class from a common base class used in the map.
The upside to this is that a getKeys() method can present all of the keys available in the class -- something quite useful for dynamic GUIs and message handling.
If you are using a library in which everything subclasses some Object class (QObject for example), you can use a map of (string, object) to hold all your data and then access it with:
Object get(string name) { return memebers[name]; }
members is std::map<std::string, Object>
You will need to use type casts of course.
Button* my_var = static_cast<Button*>(my_class.get("my_button"));
// get returns Object
You can also use Qt's property system if you use Qt. This is not standard c++, but qmake and moc work on many operating systems.
all right.since you know what you want.
void get(int flag, void *return_value)
get the return_value typd casting to what you want.
thanks

Specifying template arguments from variables in C++

I want to instantiate a template class with data types that are available at runtime in variables. For example, consider this class:
template <typename T, unsigned int U>
class Allocator
{
public:
T * pointer;
Allocator() { pointer = new T[U]; }
~Allocator() { delete [] pointer; }
};
Now I want to use it like this:
int main()
{
string temp = "int";
unsigned int count = 64;
Allocator<temp, count> a;
return 0;
}
Is there any way of doing this?
I am facing this problem in the context of serializing derived classes with base pointers. I use RTTI to identify the real type of derived class, but the information of the real type is stored in a string. My problem is to be able to dynamic_cast to the type (available as a string at runtime) from the base pointer. Please help.
You can't. Data types must be known at compile time. Maybe using Boost or unions may solve the problem in a non-pretty way.
Good luck!
The absence of a reflection mechanism in C++ makes practically impossible the "dynamic creation" based on data with a direct language support.
The only way is to use a "switch", or any equivalent declarative mechanism, like a factory class owning a dispatch map that associate the strings declaring the type to creation function calls.