-
November 26th, 2010, 04:57 PM
#1
Something like boost::any
I was working out a way to implement some type of generic object, something similar to boost::any. I don't have any boost sources laying around, so I'm not quite sure how they achieve it.
This is what I came up with so far:
Code:
template <typename T>
inline const char* TypeOf()
{
return typeid(T).name();
}
template <typename T>
inline const char* TypeOf(T obj)
{
return typeid(obj).name();
}
class Object
{
void* ptr;
const char* m_type;
public:
template <typename T>
Object(T obj)
{
m_type = TypeOf(obj);
ptr = new T(obj);
}
Object(Object& obj)
{
m_type = obj.m_type;
ptr = obj.ptr;
obj.ptr = 0;
}
~Object()
{
if(ptr) delete ptr;
}
template <typename T>
operator T()
{
return *((T*)ptr);
}
const char* Type() const
{
return m_type;
}
};
Code:
int main()
{
vector<Object> objects;
objects.push_back(42);
objects.push_back(88);
objects.push_back(3.14159f);
objects.push_back('c');
objects.push_back(string("Hello!"));
objects.push_back(1337L);
auto lambda = [](Object obj)
{
if(obj.Type() == TypeOf<int>())
{
cout << static_cast<int>(obj) << "\n";
}
else if(obj.Type() == TypeOf<float>())
{
cout << static_cast<float>(obj) << "\n";
}
else if(obj.Type() == TypeOf<char>())
{
cout << static_cast<char>(obj) << "\n";
}
else if(obj.Type() == TypeOf<string>())
{
cout << static_cast<string>(obj) << "\n";
}
else
{
cout << "Unknown type" << "\n";
}
};
for_each(objects.begin(), objects.end(), lambda);
system("PAUSE");
return 0;
}
-
November 26th, 2010, 07:11 PM
#2
Re: Something like boost::any
Originally Posted by Chris_F
I was working out a way to implement some type of generic object, something similar to boost::any. I don't have any boost sources laying around, so I'm not quite sure how they achieve it.
I don't think that type_info::name is guaranteed to return a unique name for each type.
Couple of points about your code:
Originally Posted by Chris_F
Code:
Object(Object& obj)
{
m_type = obj.m_type;
ptr = obj.ptr;
obj.ptr = 0;
}
That's not a good idea. This gives you the same behavior as std::auto_ptr, which will be deprecated in C++0x for good reason. You won't be able to safely store your objects in a vector (which seems somewhat the point of having a class like boost::any).
Since you are using other C++0x features, why not make the object movable?
Originally Posted by Chris_F
Code:
~Object()
{
if(ptr) delete ptr;
}
Deleting a void* is undefined behavior.
Cheers, D Drmmr
Please put [code][/code] tags around your code to preserve indentation and make it more readable.
As long as man ascribes to himself what is merely a posibility, he will not work for the attainment of it. - P. D. Ouspensky
-
November 27th, 2010, 07:58 AM
#3
Re: Something like boost::any
First, boost::any does not use a void* in its implementation of the type. Second, you would need to have type_info to store type information on the encapsulated object but you shouldn't use the name for the reason as suggested by D_Drmmr.
Have a look at this blogpost for some background on boost::any: here and then you can also refer to the boost code by following the link provided there. If you do have boost on your system, you should be able to access their code.
Can you help me with my homework assignment?, Before you post!, Use code tags, How to post!, Codeguru technical FAQs, C++ FAQ Lite, Stroustrup: C++ Style and Technique FAQ, Guru of the Week, Comeau C and C++ FAQs, Comeau C++ Templates FAQs, CUJ @ DDJ, Spam threshold
My Blogs : Learning C++ is fun | Abnegator's reflections
Open Threads : C++ Aha! Moments | Nature of work in C++?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|