There is a class defined in a library:
class fromLib{};
used as argument to invoke a method implemented within the library :
method_from_lib(const fromLib& from_lib){};
I want wrap this method within an interface
class Methods{
virtual invoke_method(const& genericArg)
}
where class genericArg is generic representation of fromLib.
A simple implementation would be:
class MethodImpl: public Methods {
invoke_method(const genericArg& arg) {
method_from_lib(arg); // this is not going to work since the argument is not an instance of `fromLib` nor convertible nor does it inherit from it.
};
}
In an ideal world, I would have made the class fromLib directly inherit from genericArg . However, this is not possible given that this class is from a library that I really dont want to touch.
How would I achieve a wrapper around fromLib which is also an implemetation of genericArg.
The motivation for this is the following:
A library provides some method with the signature method_from_lib(const fromLib& from_lib){}; that we might or might not use. We potentially want to either use that method or some other implementation. If we were to use some other implementation the argument to the function would also need to change since the argument fromLib is tightly coupled to the implementation provided by the library.
Therefore, providing an interface for the method itself is straightforward, however, the purpose of this question is to how we can generalize the argument fromLib into some interface. So that our interface would be like
class Methods{
virtual invoke_method(const& genericArg)
}
When we want to implement the case with using the library, the implementation is fairly easy we just invoke the method from the library i.e.
invoke_method(const TYPE& arg) {
method_from_lib(arg);
};
Now as you see implementing this method either requires the TYPE to be genericArg or some class that inherits from it. The problem here is that method_from_lib expects the type fromLib which we cannot directly make as a child from genericArg since that type is contained in a thirdparty library
I think you're looking for an adapter.
https://refactoring.guru/design-patterns/adapter/cpp/example
Usage examples: The Adapter pattern is pretty common in C++ code. It’s
very often used in systems based on some legacy code. In such cases,
Adapters make legacy code work with modern classes.
Identification: Adapter is recognizable by a constructor which takes
an instance of a different abstract/interface type. When the adapter
receives a call to any of its methods, it translates parameters to the
appropriate format and then directs the call to one or several methods
of the wrapped object.
You state you don't want to touch the fromLib class. Under the assumption that the data required by fromLib will definitely be required for the operation that is to be executed, you'll have to implement your own struct which contains the required data.
This own struct can then be passed to the adapter. The adapter will then pass it on to the lib, and return the correct result. If you want to switch out the lib, you switch out the adapter to work with the new lib. The rest of your code will remain unchanged.
E.g.:
class fromLib{
int degrees;// You can't change this even if you'd want to use radians in your program.
}
struct myActualRequiredData {
double radians;// Choose something here which works well within your own program.
}
class MethodsTarget{
virtual invoke_method(const myActualRequiredData& data);
}
class MethodsAdapter : public MethodsTarget{
virtual invoke_method(const myActualRequiredData& data) {
fromLib myFromLib = {
.degrees = radians * 360 / PI;// Or so. I currently don't care, not what your question is about. In any case, here's where you do all the work to speak the libraries language.
};
method_from_lib(myFromLib);
}
};
MethodsAdapter adapter;
adapter.invoke_method({
.radians = 0.2
});
// Oh look I found a better lib
class fromLib2{
std::string degrees;
}
class MethodsAdapter2 : public MethodsTarget {
virtual invoke_method(const myActualRequiredData& data) {
fromLib2 myFromLib = {
.degrees = std::string(radians * 360 / PI);
};
method_from_lib(myFromLib);
}
}
MethodsAdapter2 adapter2;
adapter.invoke_method({
.radians = 0.2
});
This example shows that changing the library will lead to minimal adjustment when using the adapter pattern.
Use with pointers to MethodsTarget if necessary. But usually for libs, simply having one adapter class should be enough. You won't be hotswapping anyways.
I would suggest using composition and passing the member into the library call:
struct GenericArg{
fromLib member;
};
void wrapper(const GenericArg& arg){
method_from_lib(arg.member);
}
Related
One of the nice things in Java is implementing interface. For example consider the following snippet:
interface SimpleInterface()
{
public: void doThis();
}
...
SimpleInterface simple = new SimpleInterface()
{
#Override public doThis(){ /**Do something here*/}
}
The only way I could see this being done is through Lambda in C++ or passing an instance of function<> to a class. But I am actually checking if this is possible somehow? I have classes which implements a particular interface and these interfaces just contain 1-2 methods. I can't write a new file for it or add a method to a class which accepts a function<> or lambda so that it can determine on what to do. Is this strictly C++ limitation? Will it ever be supported?
Somehow, I wanted to write something like this:
thisClass.setAction(int i , new SimpleInterface()
{
protected:
virtual void doThis(){}
});
One thing though is that I haven't check the latest spec for C++14 and I wanted to know if this is possible somehow.
Thank you!
Will it ever be supported?
You mean, will the language designers ever add a dirty hack where the only reason it ever existed in one language was because those designers were too stupid to add the feature they actually needed?
Not in this specific instance.
You can create a derived class that derives from it and then uses a lambda, and then use that at your various call sites. But you'd still need to create one converter for each interface.
struct FunctionalInterfaceImpl : SimpleInterface {
FunctionalInterfaceImpl(std::function<void()> f)
: func(f) {}
std::function<void()> func;
void doThis() { func(); }
};
You seem to think each class needs a separate .h and .cpp file. C++ allows you to define a class at any scope, including local to a function:
void foo() {
struct SimpleInterfaceImpl : SimpleInterface
{
protected:
void doThis() override {}
};
thisClass.setAction(int i , new SimpleInterfaceImpl());
}
Of course, you have a naked new in there which is probably a bad idea. In real code, you'd want to allocate the instance locally, or use a smart pointer.
This is indeed a "limitation" of C++ (and C#, as I was doing some research some time ago). Anonymous java classes are one of its unique features.
The closest way you can emulate this is with function objects and/or local types. C++11 and later offers lambdas which are semantic sugar of those two things, for this reason, and saves us a lot of writing. Thank goodness for that, before c++11 one had to define a type for every little thing.
Please note that for interfaces that are made up of a single method, then function objects/lambdas/delegates(C#) are actually a cleaner approach. Java uses interfaces for this case as a "limitation" of its own. It would be considered a Java-ism to use single-method interfaces as callbacks in C++.
Local types are actually a pretty good approximation, the only drawback being that you are forced to name the types (see edit) (a tiresome obligation, which one takes over when using static languages of the C family).
You don't need to allocate an object with new to use it polymorphically. It can be a stack object, which you pass by reference (or pointer, for extra anachronism). For instance:
struct This {};
struct That {};
class Handler {
public:
virtual ~Handler ();
virtual void handle (This) = 0;
virtual void handle (That) = 0;
};
class Dispatcher {
Handler& handler;
public:
Dispatcher (Handler& handler): handler(handler) { }
template <typename T>
void dispatch (T&& obj) { handler.handle(std::forward<T>(obj)); }
};
void f ()
{
struct: public Handler {
void handle (This) override { }
void handle (That) override { }
} handler;
Dispatcher dispatcher { handler };
dispatcher.dispatch(This {});
dispatcher.dispatch(That {});
}
Also note the override specifier offered by c++11, which has more or less the same purpose as the #Override annotation (generate a compile error in case this member function (method) does not actually override anything).
I have never heard about this feature being supported or even discussed, and I personally don't see it even being considered as a feature in C++ community.
EDIT right after finishing this post, I realised that there is no need to name local types (naturally), so the example becomes even more java-friendly. The only difference being that you cannot define a new type within an expression. I have updated the example accordingly.
In c++ interfaces are classes which has pure virtual functions in them, etc
class Foo{
virtual Function() = 0;
};
Every single class that inherits this class must implement this function.
I am wrapping a library which I did not write to make it more user friendly. There are a huge number of functions which are very basic so it's not ideal to have to wrap all of these when all that is really required is type conversion of the results.
A contrived example:
Say the library has a class QueryService, it has among others this method:
WeirdInt getId() const;
I'd like a standard int in my interface however, I can get an int out of WeirdInt no problem as I know how to do this. In this case lets say that WeirdInt has:
int getValue() const;
This is a very simple example, often the type conversion is more complicated and not always just a call to getValue().
There are literally hundreds of function calls that return types likes these and more are added all the time, so I'd like to try and reduce the burden on myself having to constantly add a bajillion methods every time the library does just to turn WeirdType into type.
I want to end up with a QueryServiceWrapper which has all the same functionality as QueryService, but where I've converted the types. Am I going to have to write an identically names method to wrap every method in QueryService? Or is there some magic I'm missing? There is a bit more to it as well, but not relevant to this question.
Thanks
The first approach I'd think is by trying with templates such that
you provide a standard implementation for all the wrapper types which have a trivial getValue() method
you specialize the template for all the others
Something like:
class WeirdInt
{
int v;
public:
WeirdInt(int v) : v(v) { }
int getValue() { return v; }
};
class ComplexInt
{
int v;
public:
ComplexInt(int v) : v(v) { }
int getValue() { return v; }
};
template<typename A, typename B>
A wrap(B type)
{
return type.getValue();
}
template<>
int wrap(ComplexInt type)
{
int v = type.getValue();
return v*2;
};
int x = wrap<int, WeirdInt>(WeirdInt(5));
int y = wrap<int, ComplexInt>(ComplexInt(10));
If the wrapper methods for QueryService have a simple pattern, you could also think of generating QueryServiceWrapper with some perl or python script, using some heuristics. Then you need to define some input parameters at most.
Even defining some macros would help in writing this wrapper class.
Briefly, If your aim is to encapsulate the functionality completely so that WeirdInt and QueryService are not exposed to the 'client' code such that you don't need to include any headers which declare them in the client code, then I doubt the approach you take will be able to benefit from any magic.
When I've done this before, my first step has been to use the pimpl idiom so that your header contains no implementation details as follows:
QueryServiceWrapper.h
class QueryServiceWrapperImpl;
class QueryServiceWrapper
{
public:
QueryServiceWrapper();
virtual ~QueryServiceWrapper();
int getId();
private:
QueryServiceWrapperImpl impl_;
};
and then in the definition, you can put the implementation details, safe in the knowledge that it will not leach out to any downstream code:
QueryServiceWrapper.cpp
struct QueryServiceWrapperImpl
{
public:
QueryService svc_;
};
// ...
int QueryServiceWrapper::getValue()
{
return impl_->svc_.getId().getValue();
}
Without knowing what different methods need to be employed to do the conversion, it's difficult add too much more here, but you could certainly use template functions to do conversion of the most popular types.
The downside here is that you'd have to implement everything yourself. This could be a double edged sword as it's then possible to implement only that functionality that you really need. There's generally no point in wrapping functionality that is never used.
I don't know of a 'silver bullet' that will implement the functions - or even empty wrappers on the functions. I've normally done this by a combination of shell scripts to either create the empty classes that I want or taking a copy of the header and using text manipulation using sed or Perl to change original types to the new types for the wrapper class.
It's tempting in these cases to use public inheritance to enable access to the base functions while allowing functions to be overridden. However, this is not applicable in your case as you want to change return types (not sufficient for an overload) and (presumably) you want to prevent exposure of the original Weird types.
The way forward here has to be to use aggregation although in such as case there is no way you can easily avoid re-implementing (some of) the interfaces unless you are prepared to automate the creation of the class (using code generation) to some extent.
more complex approach is to introduce a required number of facade classes over original QueryService, each of which has a limited set of functions for one particular query or query-type. I don't know that your particular QueryService do, so here is an imaginary example:
suppose the original class have a lot of weired methods worked with strange types
struct OriginQueryService
{
WeirdType1 query_for_smth(...);
WeirdType1 smth_related(...);
WeirdType2 another_query(...);
void smth_related_to_another_query(...);
// and so on (a lot of other function-members)
};
then you may write some facade classes like this:
struct QueryFacade
{
OriginQueryService& m_instance;
QueryFacade(OriginQueryService* qs) : m_instance(*qs) {}
// Wrap original query_for_smth(), possible w/ changed type of
// parameters (if you'd like to convert 'em from C++ native types to
// some WeirdTypeX)...
DesiredType1 query_for_smth(...);
// more wrappers related to this particular query/task
DesiredType1 smth_related(...);
};
struct AnotherQueryFacade
{
OriginQueryService& m_instance;
AnotherQueryFacade(OriginQueryService* qs) : m_instance(*qs) {}
DesiredType2 another_query(...);
void smth_related_to_another_query(...);
};
every method delegate call to m_instance and decorated w/ input/output types conversion in a way you want it. Types conversion can be implemented as #Jack describe in his post. Or you can provide a set of free functions in your namespace (like Desired fromWeird(const Weired&); and Weired toWeired(const Desired&);) which would be choosen by ADL, so if some new type arise, all that you have to do is to provide overloads for this 2 functions... such approach work quite well in boost::serialization.
Also you may provide a generic (template) version for that functions, which would call getValue() for example, in case if lot of your Weired types has such member.
I am looking for some design advices for the following problem:
I am using boost geometry, I have a couple of custom geometry types compatible with boost geometry (via traits), but most of the types I am using are typedefs.
class MyPoint
{
// custom stuff
};
// declare traits for MyPoint for use wih boost geometry here
class MyTaggedPoint : public MyPoint
{
// more custom stuff
};
// declare traits for MyTaggedPoint for use wih boost geometry here
// example typedefs
typedef boost::geometry::model::polygon<MyPoint> Polygon;
typedef boost::geometry::model::polygon<MyTaggedPoint> TaggedPolygon;
My problem is when I want to serialize/deserialize my geometries.
Let's say all geometries are stored in a binary field in a database. If I would have a base geometry class, I would probably just write g->type() (4 bytes) and call g->save(some_outputstream) and write all of that to the binary field. Then when reading the binary field I would simply read the bytes and cast to appropriate geometry type.
But Boost geometries do not have a common base class.
How do you guys usually approach serialization when there are multiple types that can be stored as binary and you do not have a shared base class ?
I was thinking of maybe having a Serializer class, that returns a boost.Any and then the geometry can be casted afterward with the type that would be stored in the (de)serializer? But then the serializer would need a save method for each geometry types ? ex: Save(myPolygon), Save(myPoint)
Any ideas/experiences?
Boost's serialization supports non-invasive serialization if you do not wish to reimplement the wheel. You may even be able to find library support for their geometry types somewhere. The interface is somewhat complicated due to XML concerns unfortunately.
To serialize objects to and from bytes, you ultimately need 2 functions for EACH type you have to support (primatives, objects, etc.). These are "Load()" and "Store()".
Ideally, you use a fixed interface for the bytes- a iostream, char*, some buffer object- etc.
For the sake of readability let's call it "ByteBuffer", since logically that's what its role is.
We now have something like template functions for the Serializable concept:
template<typename T>
ByteBuffer Store(const T& object) { // BUT, What goes here...? }
template<typename T>
T Load(const ByteBuffer& bytes);
Okay, this isn't going to work for anything other than the primitive types- even if we made these "visitors" or something they literally have to know every detail about the object's internals to do their job. Furthermore, "Load()" is logically a constructor (really, a FACTORY since it could easily fail). We've got to associate these with the actual objects.
To make Serializable a base class, we need to use the "curiously recurring template" pattern. To do this, we require all derived classes to have a constructor of the form:
T(const ByteBuffer& bytes);
To check for errors, we can provide a protected flag "valid" in the base class that derived constructors can set. Note that your object has to support factory-style construction anyway for Load() to work well with it.
Now we can do this right, providing "Load" as a factory:
template<typename T>
class Serializable // If you do reference-counting on files & such, you can add it here
{
protected:
bool valid;
// Require derived to mark as valid upon load
Serializable() : valid(false) {}
virtual ~Serializable() { valid = false; }
public:
static T Load(const ByteBuffer& bytes); // calls a "T(bytes)" constructor
// Store API
virtual ByteBuffer Store() = 0; // Interface details are up to you.
};
Now, just derive from the base class like so and you can pick up everything you need:
class MyObject : public Serializable<MyObject>
{
protected:
// .. some members ...
MyObject(const ByteBuffer& bytes)
{
//... Actual load logic for this object type ...
// On success only:
valid = true;
}
public:
virtual ByteBuffer Store() {
//... store logic
}
};
What's cool is that you can call "MyObject::Load()" and it'll do exactly what you expect. Futhermore, "Load" can be made into the ONLY way to build the object, allowing you clean APIs for read-only files and such.
Extending this to full File APIs takes a little more work, namely adding a "Load()" that can read from a larger buffer (holding other things) and "Store()" that appends to an existing buffer.
As a side note, do NOT use boost's APIs for this. In a good design serializable objects should map 1-to-1 to packed structures of primitive types on disk- that's the only way the resulting files are really going to be usable by other programs or on other machines. Boost gives you a horrible API that mostly enables you to do things you'll regret later.
I have a simple, low-level container class that is used by a more high-level file class. Basically, the file class uses the container to store modifications locally before saving a final version to an actual file. Some of the methods, therefore, carry directly over from the container class to the file class. (For example, Resize().)
I've just been defining the methods in the file class to call their container class variants. For example:
void FileClass::Foo()
{
ContainerMember.Foo();
}
This is, however, growing to be a nuisance. Is there a better way to do this?
Here's a simplified example:
class MyContainer
{
// ...
public:
void Foo()
{
// This function directly handles the object's
// member variables.
}
}
class MyClass
{
MyContainer Member;
public:
void Foo()
{
Member.Foo();
// This seems to be pointless re-implementation, and it's
// inconvenient to keep MyContainer's methods and MyClass's
// wrappers for those methods synchronized.
}
}
Well, why not just inherit privatly from MyContainer and expose those functions that you want to just forward with a using declaration? That is called "Implementing MyClass in terms of MyContainer.
class MyContainer
{
public:
void Foo()
{
// This function directly handles the object's
// member variables.
}
void Bar(){
// ...
}
}
class MyClass : private MyContainer
{
public:
using MyContainer::Foo;
// would hide MyContainer::Bar
void Bar(){
// ...
MyContainer::Bar();
// ...
}
}
Now the "outside" will be able to directly call Foo, while Bar is only accessible inside of MyClass. If you now make a function with the same name, it hides the base function and you can wrap base functions like that. Of course, you now need to fully qualify the call to the base function, or you'll go into an endless recursion.
Additionally, if you want to allow (non-polymorphical) subclassing of MyClass, than this is one of the rare places, were protected inheritence is actually useful:
class MyClass : protected MyContainer{
// all stays the same, subclasses are also allowed to call the MyContainer functions
};
Non-polymorphical if your MyClass has no virtual destructor.
Yes, maintaining a proxy class like this is very annoying. Your IDE might have some tools to make it a little easier. Or you might be able to download an IDE add-on.
But it isn't usually very difficult unless you need to support dozens of functions and overrides and templates.
I usually write them like:
void Foo() { return Member.Foo(); }
int Bar(int x) { return Member.Bar(x); }
It's nice and symmetrical. C++ lets you return void values in void functions because that makes templates work better. But you can use the same thing to make other code prettier.
That's delegation inheritance and I don't know that C++ offers any mechanism to help with that.
Consider what makes sense in your case - composition (has a) or inheritance (is a) relationship between MyClass and MyContainer.
If you don't want to have code like this anymore, you are pretty much restricted to implementation inheritance (MyContainer as a base/abstract base class). However you have to make sure this actually makes sense in your application, and you are not inheriting purely for the implementation (inheritance for implementation is bad).
If in doubt, what you have is probably fine.
EDIT: I'm more used to thinking in Java/C# and overlooked the fact that C++ has the greater inheritance flexibility Xeo utilizes in his answer. That just feels like nice solution in this case.
This feature that you need to write large amounts of code is actually necessary feature. C++ is verbose language, and if you try to avoid writing code with c++, your design will never be very good.
But the real problem with this question is that the class has no behaviour. It's just a wrapper which does nothing. Every class needs to do something other than just pass data around.
The key thing is that every class has correct interface. This requirement makes it necessary to write forwarding functions. The main purpose of each member function is to distribute the work required to all data members. If you only have one data member, and you've not decided yet what the class is supposed to do, then all you have is forwarding functions. Once you add more member objects and decide what the class is supposed to do, then your forwarding functions will change to something more reasonable.
One thing which will help with this is to keep your classes small. If the interface is small, each proxy class will only have small interface and the interface will not change very often.
I'm building an hierarchy of objects that wrap primitive types, e.g integers, booleans, floats etc, as well as container types like vectors, maps and sets. I'm trying to (be able to) build an arbitrary hierarchy of objects, and be able to set/get their values with ease. This hierarchy will be passed to another class (not mentioned here) and an interface will be created from this representation. This is the purpose of this hierarchy, to be able to create a GUI representation from these objects.To be more precise, i have something like this:
class ValObject
{
public:
virtual ~ValObject() {}
};
class Int : public ValObject
{
public:
Int(int v) : val(v) {}
void set_int(int v) { val = v);
int get_int() const { return val; }
private:
int val;
};
// other classes for floats, booleans, strings, etc
// ...
class Map : public ValObject {}
{
public:
void set_val_for_key(const string& key, ValObject* val);
ValObject* val_for_key(const string& key);
private:
map<string, ValObject*> keyvals;
};
// classes for other containers (vector and set) ...
The client, should be able to create and arbitrary hierarchy of objects, set and get their values with ease, and I, as a junior programmer, should learn how to correctly create the classes for something like this.
The main problem I'm facing is how to set/get the values through a pointer to the base class ValObject. At first, i thought i could just create lots of functions in the base class, like set_int, get_int, set_string, get_string, set_value_for_key, get_value_for_key, etc, and make them work only for the correct types. But then, i would have lots of cases where functions do nothing and just pollute my interface. My second thought was to create various proxy objects for setting and getting the various values, e.g
class ValObject
{
public:
virtual ~ValObject() {}
virtual IntProxy* create_int_proxy(); // <-- my proxy
};
class Int : public ValObject
{
public:
Int (int v) : val(v) {}
IntProxy* create_int_proxy() { return new IntProxy(&val); }
private:
int val;
};
class String : public ValObject
{
public:
String(const string& s) : val(s) {}
IntProxy* create_int_proxy() { return 0; }
private:
string val;
};
The client could then use this proxy to set and get the values of an Int through an ValObject:
ValObject *val = ... // some object
IntProxy *ipr = val->create_int_proxy();
assert(ipr); // we know that val is an Int (somehow)
ipr->set_val(17);
But with this design, i still have too many classes to declare and implement in the various subclasses. Is this the correct way to go ? Are there any alternatives ?
Thank you.
Take a look at boost::any and boost::variant for existing solutions. The closest to what you propose is boost::any, and the code is simple enough to read and understand even if you want to build your own solution for learning purposes --if you need the code, don't reinvent the wheel, use boost::any.
One of the beauties of C++ is that these kinds of intrusive solutions often aren't necessary, yet unfortunately we still see similar ones being implemented today. This is probably due to the prevalence of Java, .NET, and QT which follows these kinds of models where we have a general object base class which is inherited by almost everything.
By intrusive, what's meant is that the types being used have to be modified to work with the aggregate system (inheriting from a base object in this case). One of the problems with intrusive solutions (though sometimes appropriate) is that they require coupling these types with the system used to aggregate them: the types become dependent on the system. For PODs it is impossible to use intrusive solutions directly as we cannot change the interface of an int, e.g.: a wrapper becomes necessary. This is also true of types outside your control like the standard C++ library or boost. The result is that you end up spending a lot of time and effort manually creating wrappers to all kinds of things when such wrappers could have been easily generated in C++. It can also be very pessimistic on your code if the intrusive solution is uniformly applied even in cases where unnecessary and incurs a runtime/memory overhead.
With C++, a plethora of non-intrusive solutions are available at your fingertips, but this is especially true when we know that we can combine static polymorphism using templates with dynamic polymorphism using virtual functions. Basically we can generate these base object-derived wrappers with virtual functions on the fly only for the cases in which this solution is needed without pessimizing the cases where this isn't necessary.
As already suggested, boost::any is a great model for what you want to achieve. If you can use it directly, you should use it. If you can't (ex: if you are providing an SDK and cannot depend on third parties to have matching versions of boost), then look at the solution as a working example.
The basic idea of boost::any is to do something similar to what you are doing, only these wrappers are generated at compile-time. If you want to store an int in boost::any, the class will generate an int wrapper class which inherits from a base object that provides the virtual interface required to make any work at runtime.
The main problem I'm facing is how to
set/get the values through a pointer
to the base class ValObject. At first,
i thought i could just create lots of
functions in the base class, like
set_int, get_int, set_string,
get_string, set_value_for_key,
get_value_for_key, etc, and make them
work only for the correct types. But
then, i would have lots of cases where
functions do nothing and just pollute
my interface.
As you already correctly deduced, this would generally be an inferior design. One tell-tale sign of inheritance being used improperly is when you have a lot of base functions which are not applicable to your subclasses.
Consider the design of I/O streams. We don't have ostreams with functions like output_int, output_float, output_foo, etc. as being directly methods in ostream. Instead, we can overload operator<< to output any data type we want in a non-intrusive fashion. A similar solution can be achieved for your base type. Do you want to associate widgets with custom types (ex: custom property editor)? We can allow that:
shared_ptr<Widget> create_widget(const shared_ptr<int>& val);
shared_ptr<Widget> create_widget(const shared_ptr<float>& val);
shared_ptr<Widget> create_widget(const shared_ptr<Foo>& val);
// etc.
Do you want to serialize these objects? We can use a solution like I/O streams. If you are adapting your own solution like boost::any, it can expect such auxiliary functions to already be there with the type being stored (the virtual functions in the generated wrapper class can call create_widget(T), e.g.
If you cannot be this general, then provide some means of identifying the types being stored (a type ID, e.g.) and handle the getting/setting of various types appropriately in the client code based on this type ID. This way the client can see what's being stored and deal set/get values on it accordingly.
Anyway, it's up to you, but do consider a non-intrusive approach to this as it will generally be less problematic and a whole lot more flexible.
Use dynamic_cast to cast up the hierarchy. You don't need to provide an explicit interface for this - any reasonable C++ programmer can do that. If they can't do that, you could try enumerating the different types and creating an integral constant for each, which you can then provide a virtual function to return, and you can then static_cast up.
Finally, you could consider passing a function object, in double-dispatch style. This has a definite encapsulation advantage.
struct functor {
void operator()(Int& integral) {
...
}
void operator()(Bool& boo) {
...
}
};
template<typename Functor> void PerformOperationByFunctor(Functor func) {
if (Int* ptr = dynamic_cast<Int*>(this)) {
func(*ptr);
}
// Repeat
}
More finally, you should avoid creating types where they've basically been already covered. For example, there's little point providing a 64bit integral type and a 32bit integral type and ... it's just not worth the hassle. Same with double and float.