Is it possible to store a type name as a C++ variable? For example, like this:
type my_type = int; // or string, or Foo, or any other type
void* data = ...;
my_type* a = (my_type*) data;
I know that 99.9% of the time there's a better way to do what you want without resorting to casting void pointers, but I'm curious if C++ allows this sort of thing.
No, this is not possible in C++.
The RTTI typeid operator allows you to get some information about types at runtime: you can get the type's name and check whether it is equal to another type, but that's about it.
Not as written, but you could do something similar...
class Type
{
public:
virtual ~Type(){}
virtual void* allocate()const=0;
virtual void* cast(void* obj)const=0;
};
template<typename T> class TypeImpl : public Type
{
public:
virtual void* allocate()const{ return new T; }
virtual void* cast(void* obj)const{ return static_cast<T*>(obj); }
};
// ...
Type* type = new TypeImpl<int>;
void* myint = type->allocate();
// ...
This kind of thing can be extended depending on what features you need.
You can't do that in C++, but you can use the boost any library then test for the type it holds. Example:
bool is_int(const boost::any & operand)
{
return operand.type() == typeid(int);
}
http://www.boost.org/doc/libs/1_42_0/doc/html/any/s02.html
No you can't store the type directly as you want, but you can instead store the name of the type.
const char* str = typeid(int).name();
I guess whenever you planned to use that variable for comparison, you could instead at that time compare the str variable against the name() of the types.
const char* myType = typeid(int).name();
//....
//Some time later:
if(!strcmp(myType, typeid(int).name()))
{
//Do something
}
More info available here
Yes, if you code it yourself.
enum Foo_Type{
AFOO,
B_AFOO,
C_AFOO,
RUN
};
struct MyFoo{
Foo_Type m_type;
Boost::shared_ptr<Foo> m_foo;
}
as commented below, what I left out was that all these "foo" types would have to be related to Foo. Foo would, in essence, be your interface.
Today I had a similar problem while coding:
I had the need to store a polymoriphic data type (here named refobj) over wich call functions of the concrete classes implementing it. I need a solution that doesn't cast the variable explicitly because I need to reduce the amount of code.
My solution (but I haven't tested it yet) looks similar to a previous answer. Actually is quite an experimental solution. It look like this...
// interface to use in the function
class Type
{
public:
virtual void* getObj()const=0;
};
// here the static_cast with the "stored" type
template<typename T> class TypeImpl : public Type
{
public:
TypeImpl(T *obj) {myobj=obj;}
virtual void* getObj()const{ return static_cast<T*>(myobj); }
private:
T* myobj;
};
// here the type that will contain the polimorific type
// that I don't want to cast explicitly in my code
Type *refobj;
// here the "user code "
void userofTypes()
{
( refobj->getObj() ).c_str();
// getObj() should return a string type over which
// calling string concrete functions ...let's try!
}
void main()
{
refobj=new TypeImpl < string > ( new string("hello") );
userofTypes();
}
// it might seem absurd don't cast refobj explicitly, but of
// course there are situation in which it can be useful!
Types are not objects in C++ (where they are in Ruby, for instance), so you cannot store instances of a type. Actually, types never appear in the executing code (RTTI is just extra storage).
Based on your example, it looks like you're looking for typedefs.
typedef int Number;
Number one = 1;
Number* best = (Number*) one;
Note that a typedef isn't storing the type; it is aliasing the type.
A better process is to have a common base class containing a load method, and an interface for loaders. This would allow other parts of the program to load data generically without knowledge of the descendant class:
struct Load_Interface;
struct Loader
{
virtual void visit(Load_Interface&) = 0;
}
struct Load_Interface
{
virtual void accept_loader(Loader& l)
{
l.visit(*this);
}
};
This design avoids the need to know the types of objects.
Related
I am working on some compiler thing and I have multiple different types:
Box*
BoxedInt*
BoxedString*
...
They are all basically pointers to different objects, I want to create a unified type, called ObjectPointer that can represent all these pointer types. I am inclined to use void * because I do not want to have casting everywhere. What can I do? Can I do something like:
typedef Box* ObjectPointer
typedef BoxedInt* ObjectPointer
....
or there are some other way to do it? I just want a algebraic data type like thing for these pointers. By the way I am using clang.
I intend to use the new type ObjectPointer just as an usual type. It should not be a class or struct or union. Say if I have a function Box* add(BoxedInt* lhs, BoxedInt rhs) after the change it should be just ObjectPointer add(ObjectPointer lhs, ObjectPointer rhs).
In C, you can use a union type, that contains pointers of all the elements described above:
union UnifiedType {
Box* boxPtr;
BoxedInt* boxedIntPrt;
BoxedString* boxedStringPtr;
};
Look here for more.
In C++ though, you can use an (abstract if needed) superclass for all those types described and set them as extensions to it. Then, you can use a base class pointer for your needs. Look here for more.
class BoxedBase { /*....*/ }
class Box : public BoxedBase { /*....*/ }
class BoxedInt : public BoxedBase { /*....*/ }
class BoxedString : public BoxedBase { /*....*/ }
You can then typedef the pointer as this:
typedef BoxedBase* ObjectPointer
You can't define "This thing can hold any number of unrelated types." however, if you relate the types (using a base class) you can use polymorphism instead.
class Object { ... }
class Box : public Object { ... }
class BoxedInt : public Object { ... }
...
typedef Object * ObjectPointer;
From the question description, it sounds like you want to use templates. For example, if you write a function
template <typename T>
void ExampleFunction(T* object)
{
//do boxy stuff
}
you can call it with all the types you are interested in, as long as a unified function definition makes sense. You can say ExampleFunction(ptr) where ptr has any type which would make sense when substituted for T in ExampleFunction.
You can do as you suggest, (i.e. use a void *) to point to all the objects, but I would only use this option after you have exhausted all other possibilities because you will have to void * cast it and lose all compiler size / type checks (effectively a re-interpretation cast).
edit: e.g. you may need to use this when you receive "known" data from an external source which has no type information like inter-processor messages or such.
Your best option is to base class your various box classes and have the other classes inherit them. This is generally the best way in c++, since your base-class pointer can point to any of the derived classes. You will still need to cast to access the final type (e.g. BoxedInt) but you can use the safer dynamic cast; generally you can use some sort of lookup function to do this, or a factory pattern...
The standard way to solve this is polymorphism. So, as others have noted, in C++ you would write
class Object { ... };
class Box : public Object { ... };
class BoxedInt : public Box { ... };
class BoxedString : public Box { ... };
...
In C, you can do the exact same thing, even though it won't avoid the necessity to cast pointers:
typedef struct Object { ... } Object;
typedef struct Box { Object super; ... } Box;
typedef struct BoxedInt { Box super; ... } BoxedInt;
typedef struct BoxedString { Box super; ... } BoxedString;
I would like to know if it'd be possible (and if, how) to create a pointer of X value
Now, let's say I know which types would be possible to be assigned in this pointer.
For example, a pointer of X value (of course feel free to change the name of this value), that'd be able to point to variables of string, bool and a custom class
Usually what you describe is a bad idea.
void* works, for marginal values of works. It throws out all type safety, requiring you to keep track of it.
Creating a root type sort of works, but it doesn't work for primitive types, and is rather intrusive.
A boost::variant< bool*, std::string*, MyClass* > is a variable that can contain a pointer to any one of these 3 types (bool, std::string or MyClass). You will probably find it challenging to use, because it enforces type safety, and the syntax can get annoying.
Similarly, a pointer to boost::variant< bool, std::string, MyClass > may be what you want, but it doesn't let you point to bool variables you aren't fooling around with.
With full C++11 support, union can contain arbitrary types, together with an enum can let you do something very much like a boost::variant. As a downside, this requires the thing you be pointed to be a union. With or without full C++11 support, a union of pointers is reasonable. In both cases, you'll have to track the type manually and keep it in sync.
What you really need to think about is "why am I asking this?", because as with many questions, the motivation matters. You may not be asking the right question.
I learned a new expression today, so I'm going to use it, "This is an XY question", You want to do X, so you think the solution is Y, therefore you ask how to do Y. You PROBABLY should ask how to do Y instead. It's a bit like you find your front wheel on the car punctured, and you go talk to the mechanic, but you don't ask "how do I fix a puncture", you ask "How do I undo a wheelnut", and only after you've removed all wheelnuts and the car has fallen over do you realize that you should have put a jack under the car to be able to get the wheel off without the car falling over...
Sure, there are void pointers and unions, that's no big deal. However, you still need to know what your pointer is actually pointing at, otherwise you'll have bloody mess.
So generally, in C++, you probably shouldn't do that.
What you should do is wrap your "thing" in another object, that knows what the content is, and can handle it. That way, you don't have some other thing maintainng state of what the object is and how to use it.
For example, we can have this:
class AnyThing
{
public:
virtual ~AnyThing();
virtual std::string ToString() = 0;
... // other things you want to do with your "things".
};
class IntThing: public AnyThing
{
private:
int value;
public:
virtual std::string ToString() { ... convert int to string ... }
};
class StringThing : public Anything
{
private:
std::string value;
public:
virtual std::string ToString() { return value; }
}
You can use a pointer to void.
If you want a pointer that can only be used to point at those three types, then I see three options:
Create a wrapper class for each type that derives from some base-class:
class Thingy { protected: Thing() {} };
class BoolThingy : public Thingy { bool x; }
class StringThingy : public Thingy { String x; }
class CustomThingy : public Thingy { Custom x; }
...
Thingy *p = new BoolThingy;
Create a smart-pointer class, overloading assignment operators that take bool *, String *, Custom *, and also overloading the * operator (although what that would do, I don't know!)
Use a variant class (e.g. boost::variant).
But with any of the options, it's not clear how such a thing would be useful...
void* has the property to point to any data type. It actually works as a container or cubboard in which you put your variable of any data type and then pass the void* to a function.
You must know the data type of the data you passed, in order to use it.
For Example:
int main()
{
int a;
void *x=&a;
func(x);
....
}
void func(void *argument)
{
int i=*(int *)argument;
....
}
If you know the types before hand and they do not have constructors. Then you can use a union.
class CustomClass {};
union MyType
{
char const* a;
bool b;
float c;
};
MyType stuff;
MyType* ptrToStuff = &stuff;
int main()
{
ptrToStuff->a = "Plop";
ptrToStuff->b = false;
ptrToStuff->c = 12.0;
}
Boost also has an ANY type.
You can store anything in it.
boost::any x = 12;
x = new CustomClass;
x = new std::string("Hi There");
x = std::string("Plop"); // even works without pointers.
You can have a pointer to any type (object, pointer, primitive type etc.) but you can not have a pointer to a reference.
NO you cannot have a pointer pointing at objects of unspecified type. The whole point of a pointer is that it points at objects of specific type. int*x points at an int, A*a points at an A.
What you can do, of course, is to have a variable of type void* that points at nothing at all (void), but can hold any address. If you somehow remember what it is the address of, then you can use a static_cast<> to cast to an appropriate pointer. Alternatively, you can use dynamic_cast<> to find out at run-time whether your void* points to a given type. This could be implemented as follows
struct AnyPointerWrapper
{
struct null_pointer {};
struct wrong_pointer_type {};
AnyPointerWrapper() : ptr(0) {}
AnyPointerWrapper(AnyPointerWrapper const&) = default;
AnyPointerWrapper&operator=(AnyPointerWrapper const&) = default;
template<typename T>
explicit AnyPointerWrapper(T*p)
: ptr(p) {}
template<typename T>
AnyPointerWrapper&operator=(T*p)
{ ptr=p; return*this; }
bool is_null() const
{ return ptr==0; }
template<typename T>
bool is() const
{ return dynamic_cast<T*>(ptr) != 0; }
template<typename T>
T* pointer()
{
if(p==0) throw null_pointer;
T*p = dynamic_cast<T*>(ptr);
if(p==0) throw wrong_pointer_type;
return p;
}
private:
void*ptr;
};
and used like this
int X;
AnyPointerWrapper a;
assert(a.is_null());
a = &X;
assert(a.is<int>());
int*p = a.pointer<int>();
(you can add more functionality including support for const pointers). Note, however, that the dynamic_cast<> is not trivial, i.e. incurs some performance penalty. Note also that AnyPointerWrapper is not a pointer: you cannot use the -> operator to call a member function of the object whose address is stored in AnyPointerWrapper::ptr; it is merely a wrapper from which you can get an appropriate pointer.
I would like to define a completely generic mapping in c++ where I can map anything to anything.
I tried std::map but what should K and V be to make it general enough so I can map primitives or objects (as keys) to other primitives or objects (as values).
Or is there another mechanism I could use?
EDIT: For clarification, I am trying to define a relationship in the base class (from which all my classes are derived) that will allow me to attach arbitrary data to my classes. The simplest approach would be a be a name-value pair, where the above key is a string. I was wondering if i do something more generic?
Impossible- as it should be. Such a mapping would be worthless, since you can't depend on any meaningful behaviour of either key or value, and it's impossible to design either a binary relation or hash function that would be meaningful across "anything", or that could operate on any type, so it's nowhere near even the realm of possible.
Edit: There is nothing preventing std::unordered_map<std::string, boost::any>- or indeed, boost::any which happens to hold a std::unordered_map of some types.
However, your design appears highly questionable. You're basically completely subverting the compiler for no apparent benefit. Why would you derive every class from a common base? And why on earth would you want to attach arbitrary data? The usual way to put data in a class is to put it in the class, not blow all your safety and performance and sanity by trying to coerce C++ into being an interpreted language.
It is possible - so in this point I disagree with #DeadMG.
It is worthless - in this point full agreement,
However I do not understand that concept of answering, I mean "don't do it" answers instead "it can be done in this way, but my advise is don't do it". I do not pretend to be "life teacher" - I am just answering,
For values - use something like boost::any.
For keys - it is more complicated - because std::map defines order in keys. So generic keys must follow thess rules:
If real keys types are the same - use order from the real keys
If real keys are not the same - you must define order between types (like order of typeinfo::name())
Generic keys must be copy constructible
Let see my proposal for keys (using type erasure):
template <typename T>
struct GenKeyTypeOrder;
class GenKeyImplInt {
public:
// true if before other Key in other
virtual bool before(const GenKeyImplInt&) const = 0;
// type value
virtual int typeOrder() const = 0;
virtual GenKeyImplInt* clone() const = 0;
virtual ~GenKeyImplInt() {}
};
template <typename RealKey>
class GenKeyImpl : public GenKeyImplInt {
public:
GenKeyImpl(RealKey realKey) : realKey(realKey) {}
// true if before other Key in other
virtual bool before(const GenKeyImplInt& r) const
{
const GenKeyImpl* rp = dynamic_cast<const GenKeyImpl*>(&r);
if (rp) return realKey < rp->realKey;
return typeOrder() < r.typeOrder();
}
// type value
virtual int typeOrder() const { return GenKeyTypeOrder<RealKey>::VALUE; }
virtual GenKeyImpl* clone() const { return new GenKeyImpl(*this); }
private:
RealKey realKey;
};
class GenKey {
public:
// true if before other Key in other
friend bool operator < (const GenKey& l, const GenKey& r)
{
return l.impl->before(*r.impl);
}
template <typename T>
GenKey(T t) : impl(new GenKeyImpl<T>(t)) {}
GenKey(const GenKey& oth) : impl(oth.impl->clone()) {}
~GenKey() { delete impl; }
private:
GenKey& operator = (const GenKey& oth); // not defined
GenKeyImplInt* impl;
};
// define for every type you want be used as generic key
template <>
struct GenKeyTypeOrder<int> { enum { VALUE = 0 }; };
template <>
struct GenKeyTypeOrder<std::string> { enum { VALUE = 1 }; };
Full example at ideone
See also this article
You will need to make K and V be special objects.
The object will need to include what object type it is.
struct {
void *pointer;
string type;
// int type; // this is also possible
} Object;
The above Object can point to anything. However, it also needs something to say what type it is, hence the type string.
Then you need to be able to cast the pointer back to the required type, by reading what is in type.
Eg.
if (type == "int") cout << (int*)(myobject.pointer) << endl;
Anyways, if you do something like this, you are almost starting to build a loosely-typed interpreter, because for any operation you want to do with the object, you will need to check its type (whether you are adding, concatenating or printing the value to stdout).
It is probably better if you use a class object, and use inheritance to store any data you need.
class Object {
public virtual string to_string() {
return "";
}
};
Then if you want to store an integer:
class Integer : public Object {
int i;
public string to_string() {
char str[50];
sprintf(str,"%d",i);
return string(str);
}
public Integer operator=(int a) {
i=a;
return this;
}
};
This way you can define an interface of all the functions you want all objects to support.
Note that making the base Object class have virtual functions means that if you say:
Integer a;
a=5;
Object object = (Object)a;
cout << object.to_string << endl; // prints "5"
So that the function called is that defined by the actual (true) type of the object.
Lets say I have a class Handler with some subclasses like stringhandler, SomeTypeHandler, AnotherTypeHandler. The class Handler defines a method "handle" as a common interface for all the subclasses. The logic to "handle" is ofcourse completely different for the different handlers.
So what I need to do is pass a value of anything to the handle method. The specific classes can then cast the "anything" to the type they expect.
Basically what I need is something like the java class Object :D
The first thing I tried was a void*, but apparently you can not do B* someB = dynamic_cast<B*>(theVoidPointer), so no luck there.
My second idea was to use boost::any. however, the requirement to use boost::any is that the value must be copy cunstructable, which is not the case for my data.
Any ideas to get this to work?
Thanks
EDIT: Note that I know I could use a SomeData class with no members at all, and let my data be subclasses of that, but I am looking for a more generic approach which does not require me to make my own wrapper class.
Okay, here is a simple approach using boost::any to hold pointers to your datatypes. However, beware that boost::any adds some overhead code decreasing performance slightly (in most cases neglectible).. consider using boost::spirit::hold_any instead, or void* if you don't need type safety.
class Handler {
public:
void handle( boost::any value ) {
do_handle( value );
}
private:
virtual void do_handle( boost::any& value ) = 0;
};
template<class T>
class HandlerBase : public Handler {
private:
void do_handle( boost::any& value ) {
// here you should check if value holds type T*...
handle_type( *(boost::any_cast<T*>( value )) );
}
void handle_type( const T& value ) = 0;
};
class StringHandler : HandlerBase<std::string> {
private:
void handle_type( const std::string& value ) {
// do stuff
}
};
Now you can write lots of handler classes, deriving from HandlerBase, without assuming that the handled types have a common base class.
You can for example define a base class:
class BaseHandlerData {
...
};
Then derive your specific data classes, which are expected by your handlers:
class StringData: public BaseHandlerData {
...
};
class SomeData: public BaseHandlerData {
...
};
Then you should be able to pass a BaseHandlerData* argument to the handle method, and use something like:
void handle(BaseHandlerData *data) {
StringData* stringData = dynamic_cast<StringData*>(...);
// handle your string data here ...
}
to safely cast to your expected data type.
Gerald
Another alternative, getting more toward the C world, would be a union type (http://en.wikipedia.org/wiki/Union_(computer_science)#C.2FC.2B.2B). This would only allow you to pass the types you specifiy, not any type, but has the type of behavior you describe.
You need to have a base class called DataObject or something. All of your data types, (string, number, whatnot) are sub classes of DataObject. The you define Handle like this:
void Handle(DataObject *dataObject);
This is a much safer way to do what you want. To make it even better, the DataObject can even know what kind of data it contains. Then the handlers can check that they've been sent the right type of data.
You can do
B* someB = static_cast<B*>(theVoidPointer);
i have a class with the following structure:
class myClass
{
private:
int type;
classOne objectOne;
classTwo objectTwo;
public:
myClass(classOne object)
{
this->objectOne = object;
this->type = 0;
}
myClass(classTwo object)
{
this->objectTwo = object;
this->type = 1;
}
}
i now want a method returning an object of type classOne if type is 0 and of type classTwo if type is 1. I do not want two methods to achieve this. the classes have different structures.
Is this even possible? Any suggestions are appreciated :)
You can use Boost.Variant to do this. A variant can be constructed directly from any value convertible to one of its bounded types. Similarly, a variant can be assigned any value convertible to one of its bounded types. Heres how you could use it in your class:
class myClass
{
private:
boost::variant<classOne, classTwo> obj;
public:
myClass(classOne object) : obj(object)
{
}
myClass(classTwo object) : obj(object)
{
}
};
It also provides a very convenient boost::get to retrieve the value from the variant.
You can use that to supply code for each bounded type you have(ie classOne and classTwo). Here is an example:
if (classOne * x = boost::get<classOne>(&obj))
{
//Code for classOne
}
else if (classTwo * x = boost::get<classTwo>(&obj)
{
//Code for classTwo
}
However, such code is quite brittle, and without careful attention will likely lead to the introduction of subtle logical errors detectable only at runtime. Thus, real-world use of variant typically demands an access mechanism more robust than get. For this reason, variant supports compile-time checked visitation via apply_visitor. Visitation requires that the programmer explicitly handle (or ignore) each bounded type. Failure to do so results in a compile-time error.
Visitation of a variant requires a visitor object. Like this:
class object_visitor
: public boost::static_visitor<>
{
public:
void operator()(classOne & x) const
{
//Code for classOne
}
void operator()(classTwo & x) const
{
//Code for classTwo
}
};
With the implementation of the above visitor, we can then apply it to obj, as seen in the following:
boost::apply_visitor( object_visitor(), obj );
Unless the two types are related (in which case you can create a function that will return a pointer/reference to the common ancestor) you cannot do that directly in C++.
C++ is a statically typed language, meaning that the type of every expression must be known at compile time, but you are trying to define a function whose return type depends on runtime values.
Depending on the particular problem to solve, there might be different approaches that you could take, including using type erasure (return a boost::any, boost::variant or your own type-erasure).
ClassOne and ClassTwo need to have the same return type then either via inheritance or composition. i.e ClassOne and ClassTwo need to be subclasses of the same super class OR they need to impl the same interface.
I am not sure why you would not use templates for your case.
You can have something like below:
template <class ClassType>
class myClass
{
private:
int type;
ClassType object;
public:
myClass(ClassType object_in)
{
this->object = object_in;
/*
C++ doesn't support reflection so I don't think there
is a robust way of doing the following at runtime.
*/
type = /* Get Type at runtime */;
}
/*
Have another method which return object in a straigtforward way.
*/
};
However, then this become trivial. Any more insight into what your use case is, such that you have to know the type?
Update:
If the ClassType is going to be an Object, you can have a const static int TypeID member for the class, which is set at compile time. You can then use it determine the Type at runtime.
If they're completely different structures, with no common base then an alternative way you can return them from the same function is to use void*.
However that's bad form in C++, usually indicating a design failure - either use two different functions, or use a common base class.
It's apples and oranges. If you put an apple into an recipe that calls for an orange it won't be the same recipe anymore.
The use of type-id is a sign that you need virtual functions for myClass. Even if the other two classes are totally independent, the fact that they are returned by the same function could easily make them inherit a base class. And also you can just return a pair containing class1, class2 and one of them can be null.
The first problem is how you will determine the class of which type has been returned. I think it is possible to return a pointer to structure of this type
struct res {
myClass* c1;
ClassOne* c2;
} ;
The field of the not chosen class is NULL, the other points to the object.