Comparing derived classes in C++ without dynamic casting or static downcasting - c++

I'm trying to compare objects of a common base class together. The comparison should fail (output a failure string, for instance) in any case when the two objects differ in class, or differ in values specific to the object. Ideally the comparison is somehow enforced, such that a new derived class would also have to write a comparison function to members of its class. Here's a code example:
#include <iostream>
#include <string>
#include <vector>
class Vehicle
{
public:
virtual std::string compareTo(Vehicle* v) = 0;
};
class Bicycle : public Vehicle
{
public:
Bicycle() { color_ = "red"; }
std::string compareTo(Vehicle* v) { return "We're different vehicles."; }
std::string compareTo(Bicycle* b) { return color_.compare(b->color_) ? "We're different bicycles." : "We're the same bicycle."; }
private:
std::string color_;
};
class Car : public Vehicle
{
public:
Car() { style_ = "sedan"; }
std::string compareTo(Vehicle* v) { return "We're different vehicles."; }
std::string compareTo(Car* c) { return style_.compare(c->style_) ? "We're different cars." : "We're the same car."; }
private:
std::string style_;
};
int main()
{
Vehicle* compareFrom = new Bicycle();
std::vector<Vehicle*> compareTos;
compareTos.push_back(new Bicycle());
compareTos.push_back(new Car());
std::vector<Vehicle*>::iterator it;
for (it = compareTos.begin(); it != compareTos.end(); ++it)
std::cout << compareFrom->compareTo(*it) << std::endl;
return 0;
}
Currently, the output (which you can see here) says "We're different vehicles". I know this is happening because I'm using the abstract base pointer. The problem is how to fix it!
The output I'd like to have is that the bicycles output that they're the same, because they do have the same color. Bicycles and cars should output that they're different vehicles. Bicycles of different colors and cars of different styles should also output that they're different. I feel like there must be a great pattern to use to solve this problem, but I'm getting mired in dynamic casting or unsafe downcast issues. Also, I would like for the comparison function to be enforced among members of the same class (so Bicycles must be able to compare to other Bicycles).

You want Multiple Dispatch (i.e. select which function to call dynamically based on more than one variable, not just 'this'). This is because you need to inspect the type somehow, otherwise the compiler will do a static analysis on the types and select what function to call (The virtual one in Vehicle).
No way around that. dynamic_cast is your friend here, but you may want to roll your own RTTI system for performance (or other) reasons. (The wikipedia article shows one way..)
std::string Bicycle::compareTo(Vehicle* v) {
if (Bicycle* b = dynamic_cast<Bicycle*>(v)) {
return compareTo(b);
} else {
return "We're different vehicles.";
}
}
There is an implementation of this pattern in the Loki C++ library which might help if you have many types that need comparing.
Multiple dispatch is not supported by the language in C++, nor in most mainstream languages. There was a proposal to add it to C++11 though, see this question and Bjarne's paper. I think it was rejected because (known and unknown) issues with dynamic linking, which the C++ standard sadly knows nothing about.

Your code has the big problem that it’s not easily extensible (violates the open/closed principle). You can however delegate the comparison to a base class method.
Also, if you want to enforce the semantic (a good thing) then you will not be able to circumvent downcasting, sorry.
To make it robust and extensible,
Make the base method pure virtual
Provide an implementation for the base method (yes, this works! Even if it’s pure virtual) that compares the objects’ types
In the derived classes, use the base class’ implementation to test for type equality, then do the actual logic check.
#include <iostream>
#include <iomanip>
#include <string>
#include <typeinfo>
struct vehicle {
virtual bool compare_to(vehicle const& other) const = 0;
};
bool vehicle::compare_to(vehicle const& other) const {
return typeid(*this) == typeid(other);
}
struct car : vehicle {
std::string color;
car(std::string const& color) : color(color) { }
bool compare_to(vehicle const& other) const {
bool result = vehicle::compare_to(other);
return result and (color == static_cast<car const&>(other).color);
}
};
struct bike : vehicle {
int spokes;
bike(int spokes) : spokes(spokes) { }
bool compare_to(vehicle const& other) const {
bool result = vehicle::compare_to(other);
return result and (spokes == static_cast<bike const&>(other).spokes);
}
};
int main() {
car c1("blue");
car c2("red");
bike b1(42);
std::cout << std::boolalpha;
std::cout << c1.compare_to(c2) << "\n"
<< c1.compare_to(b1) << "\n"
<< c1.compare_to(c1) << "\n";
}
The above code, the static_cast is safe since we have ensured beforehand that the type is the same, thus the cast will never fail.
Note that the use of typeid here is entirely legitimate. It shouldn’t even be very inefficient since there is no deep type hierarchy to walk. But if you want to make this more efficient you can implement a simple own mechanism which uses a static table in the base class to map each created instance to type-unique number identifier (e.g. std::map<vehicle*, type_id>, where type_id is a plain old enum) and perform a simple lookup.
… Or use dynamic_cast, actually.

I normally implement this using a 'kind' member in the base class. I find this has a few advantages:
Performance - no need for virtual function call and dynamic cast
By using a different 'bit' for each class type, then higher level comparisons can be made. For example 'unicycle' and 'bicycle' might both be human powered, so you could easily check for that separately from their main kind.
The kind type would look like the following:
enum Kind {
HUMAN_POWERED = (0x1 << 0),
MOTOR_POWERED = (0x1 << 1),
BICYCLE = (0x1 << 2) | HUMAN_POWERED,
UNICYCLE = (0x1 << 3) | HUMAN_POWERED,
CAR = (0x1 << 4) | MOTOR_POWERED
};
Now it's possible to check that the CAR is not a BICYCLE, but also if two types are MOTOR_POWERED or not!
bool areSameClass (Vehicle const & lhs, Vehicle const & rhs)
{
return (lhs->getKind () & rhs->getKind ()) & (HUMAN_POWERED | MOTOR_POWERED);
}

If you have RTTI enabled in your compiler, you might be able to use the typeid() operator, but this will require your classes to be polymorphic.

Related

Polymorphism Without Virtual Functions

I am trying to optimize the run time of my code and I was told that removing unnecessary virtual functions was the way to go. With that in mind I would still like to use inheritance to avoid unnecessary code bloat. I thought that if I simply redefined the functions I wanted and initialized different variable values I could get by with just downcasting to my derived class whenever I needed derived class specific behavior.
So I need a variable that identifies the type of class that I am dealing with so I can use a switch statement to downcast properly. I am using the following code to test this approach:
Classes.h
#pragma once
class A {
public:
int type;
static const int GetType() { return 0; }
A() : type(0) {}
};
class B : public A {
public:
int type;
static const int GetType() { return 1; }
B() : {type = 1}
};
Main.cpp
#include "Classes.h"
#include <iostream>
using std::cout;
using std::endl;
using std::getchar;
int main() {
A *a = new B();
cout << a->GetType() << endl;
cout << a->type;
getchar();
return 0;
}
I get the output expected: 0 1
Question 1: Is there a better way to store type so that I do not need to waste memory for each instance of the object created (like the static keyword would allow)?
Question 2: Would it be more effective to put the switch statement in the function to decide that it should do based on the type value, or switch statement -> downcast then use a derived class specific function.
Question 3: Is there a better way to handle this that I am entirely overlooking that does not use virtual functions? For Example, should I just create an entirely new class that has many of the same variables
Question 1: Is there a better way to store type so that I do not need to waste memory for each instance of the object created (like the static keyword would allow)?
There's the typeid() already enabled with RTTI, there's no need you implement that yourself in an error prone and unreliable way.
Question 2: Would it be more effective to put the switch statement in the function to decide that it should do based on the type value, or switch statement -> downcast then use a derived class specific function.
Certainly no! That's a heavy indicator of bad (sic!) class inheritance hierarchy design.
Question 3: Is there a better way to handle this that I am entirely overlooking that does not use virtual functions? For Example, should I just create an entirely new class that has many of the same variables
The typical way to realize polymorphism without usage of virtual functions is the CRTP (aka Static Polymorphism).
That's a widely used technique to avoid the overhead of virtual function tables when you don't really need them, and just want to adapt your specific needs (e.g. with small targets, where low memory overhead is crucial).
Given your example1, that would be something like this:
template<class Derived>
class A {
protected:
int InternalGetType() { return 0; }
public:
int GetType() { static_cast<Derived*>(this)->InternalGetType(); }
};
class B : public A<B> {
friend class A<B>;
protected:
int InternalGetType() { return 1; }
};
All binding will be done at compile time, and there's zero runtime overhead.
Also binding is safely guaranteed using the static_cast, that will throw compiler errors, if B doesn't actually inherits A<B>.
Note (almost disclaimer):
Don't use that pattern as a golden hammer! It has it's drawbacks also:
It's harder to provide abstract interfaces, and without prior type trait checks or concepts, you'll confuse your clients with hard to read compiler error messages at template instantiantion.
That's not applicable for plugin like architecture models, where you really want to have late binding, and modules loaded at runtime.
If you don't have really heavy restrictions regarding executable's code size and performance, it's not worth doing the extra work necessary. For most systems you can simply neglect the dispatch overhead done with virtual function defintions.
1)The semantics of GetType() isn't necessarily the best one, but well ...
Go ahead and use virtual functions, but make sure each of those functions is doing enough work that the overhead of an indirect call is insignificant. That shouldn't be very hard to do, a virtual call is pretty fast - it wouldn't be part of C++ if it wasn't.
Doing your own pointer casting is likely to be even slower, unless you can use that pointer a significant number of times.
To make this a little more concrete, here's some code:
class A {
public:
int type;
int buffer[1000000];
A() : type(0) {}
virtual void VirtualIncrease(int n) { buffer[n] += 1; }
void NonVirtualIncrease(int n) { buffer[n] += 1; }
virtual void IncreaseAll() { for i=0; i<1000000; ++i) buffer[i] += 1; }
};
class B : public A {
public:
B() : {type = 1}
virtual void VirtualIncrease(int n) { buffer[n] += 2; }
void NonVirtualIncrease(int n) { buffer[n] += 2; }
virtual void IncreaseAll() { for i=0; i<1000000; ++i) buffer[i] += 2; }
};
int main() {
A *a = new B();
// easy way with virtual
for (int i = 0; i < 1000000; ++i)
a->VirtualIncrease(i);
// hard way with switch
for (int i = 0; i < 1000000; ++i) {
switch(a->type) {
case 0:
a->NonVirtualIncrease(i);
break;
case 1:
static_cast<B*>(a)->NonVirtualIncrease(i);
break;
}
}
// fast way
a->IncreaseAll();
getchar();
return 0;
}
The code that switches using a type code is not only much harder to read, it's probably slower as well. Doing more work inside a virtual function ends up being both cleanest and fastest.

using objects of two or more data types as key for c++ map, OOP

I have a class that contains a map. Earlier, there were two maps, one with char key and one with string key. I created a class that contains enum and union and two constructors, one from char and one from string, overloaded comparison operator and used that class as key.
But I keep wondering. could this have been solved with clever use of inheritance instead?
edit:
My class is something along the lines:
class A
{
enum B
{
Ax, Ay
} b;
union C
{
X x;
Y y;
} c;
public:
A(X x) : b(Ax), c(x) {}
A(Y y) : b(Ay), c(y) {}
bool operator<(A& rhs)
{
if(this->b == rhs.b)
{
if(this->b == Ax) return this->c.x < b.c.x;
if(this->b == Ay) reutrn this->c.y < b.c.y;
}
// if the "type" is different, I assume values are different
// and all I need is any strong ordering, actual order doesn't matter
return this->b < rhs.b;
}
};
Later on I can use it fe. like that:
class Q
{
// ...
public:
Q(vector<A> v)
{
// don't worry about this code, I haven't figured out how c++11 for each
// works exactly yet, but it's not important, I can do that myself
for each (auto a in v)
{
// ...
}
}
};
Now using curly brackets I can initialize Q with various A, and I can create distinct A from char or string.
My class, Aaccomplished this by containing union for the actual data required to compare keys of one type, and enum used to compare keys of different types. Basic inheritance tree with virtual base class and two subclasses would result in every instance containing the same amount of information - different internal variables would take role of the union, and different actual classes would take the role of the enum. But I just can't come up with a way to do it properly without breaking any important principles.
Why not use boost::variant or std::variant once the latter becomes available in your compiler?
It feels like the most natural solution to the problem and makes the code very readable:
#include <boost/variant.hpp>
#include <string>
#include <map>
#include <iostream>
int main()
{
using Key = boost::variant<char, std::string>;
using Value = int; // whatever
std::map<Key, Value> map;
map['A'] = 1;
map["B"] = 2;
map["A"] = 3;
for (auto&& key_value : map)
{
std::cout << key_value.first << " => " << key_value.second << '\n';
}
}
Output:
A => 1
A => 3
B => 2
Although generally you can simplify union code with inheritance, it does not help much when you need mixed group of objects to have behavior that is aware of all other implementations.
You can make a base class, and have two subclasses - for string-based keys and for char-based keys. However, the comparison operator of string-based keys must know how to work with char-based keys, and the operator for char-based keys must know how to work with string-based keys. In situations like that the code becomes "monolithic", making a single class alternative more preferable.
In your situation, a class that exposes two constructors, and maintains a string internally should be an easy alternative:
class MyKey {
string key;
int subtype;
public:
MyKey(const string& s) : key(s), subtype(1) {}
MyKey(char c) : key(1, c), subtype(2) {}
bool operator<(MyKey& other) {
return subtype==other.subtype
? (key < other.key)
: (subtype < other.subtype);
}
};

How do you do "true" encapsulation in C++?

Encapsulation (information hiding) is a very useful concept, ensuring that only the barest minimal details are published in the API of a class.
But I can't help thinking that the way C++ does this is a little deficient. Take, for example, a (Celsius-based) temperature class like:
class tTemp {
private:
double temp;
double tempF (double);
public:
tTemp ();
~tTemp ();
setTemp (double);
double getTemp ();
double getTempF ();
};
Now, that's a very simple case but it illustrates a point that the encapsulation isn't perfect. "Real" encapsulation would hide all unnecessary information such as:
the fact that the data is maintained internally in the temp variable (and its type).
the fact that there is an internal routine for Fahrenheit/Celsius conversion.
So, ideally, it seems to me that the implementor of the class would use the above header but any client of the class would see just the public bits.
Don't get me wrong, I'm not criticising C++ since it meets the stated purpose of preventing clients from using the private bits but, for more complex classes, you could easily work out internal details based on the names, types and signatures of private data and functions.
How does C++ allow implementors to hide this information (assuming it is possible)? In C, I'd simply use an opaque type so that the internal details would be hidden but how would you do that in C++?
I suppose I could maintain an separate class, totally hidden from the client and known only to my own code, and then keep an instance of it with a void * in the visible class (casting within my code), but that seems a rather painful process. Is there an easier way in C++ to achieve the same end?
C++ uses an idiom known as "pimpl" (private implementation / pointer to implementation) to hide implementation details. Take a look at this MSDN article for details.
In short, you expose your interface in a header file as normal. Let's use your code as an example:
tTemp.h
class tTemp {
private:
class ttemp_impl; // forward declare the implementation class
std::unique_ptr<ttemp_impl> pimpl;
public:
tTemp ();
~tTemp ();
setTemp (double);
double getTemp (void);
double getTempF (void);
};
The public interface remains, but the private internals have been replaced with a smart pointer to a private implementation class. This implementation class is located only in the header's corresponding .cpp file, it is not exposed publicly.
tTemp.cpp
class tTemp::ttemp_impl
{
// put your implementation details here
}
// use the pimpl as necessary from the public interface
// be sure to initialize the pimpl!
tTtemp::tTemp() : pimpl(new ttemp_impl) {}
This also has the added advantage of allowing you to change the internals of your class without changing the header, which means less recompiling for users of your class.
For a full solution as shown in paxdiablo's pre-C++11 answer, but with unique_ptr instead of void *, you can use the following. First ttemp.h:
#include <memory>
class tTemp {
public:
tTemp();
~tTemp();
void setTemp(double);
double getTemp (void);
double getTempF (void);
private:
class impl;
std::unique_ptr<impl> pimpl;
};
Next, the "hidden" implementation in ttemp.cpp:
#include "ttemp.h"
struct tTemp::impl {
double temp;
impl() { temp = 0; };
double tempF (void) { return temp * 9 / 5 + 32; };
};
tTemp::tTemp() : pimpl (new tTemp::impl()) {};
tTemp::~tTemp() {}
void tTemp::setTemp (double t) { pimpl->temp = t; }
double tTemp::getTemp (void) { return pimpl->temp; }
double tTemp::getTempF (void) { return pimpl->tempF(); }
And, finally, ttemp_test.cpp:
#include <iostream>
#include <cstdlib>
#include "ttemp.h"
int main (void) {
tTemp t;
std::cout << t.getTemp() << "C is " << t.getTempF() << "F\n";
return 0;
}
And, like paxdiablo's solution, the output is:
0C is 32F
with the added advantage of more type safety. This answer is the ideal solution for C++11, see paxdiablo's answer if your compiler is pre-C++11.
Thought I would flesh out the "interface class / factory" technique that Don Wakefield mentions in his comment. To start with, we abstract away all implementation detail from the interface and define an abstract class that contains only the interface to a Temp:
// in interface.h:
class Temp {
public:
virtual ~Temp() {}
virtual void setTemp(double) = 0;
virtual double getTemp() const = 0;
virtual double getTempF() const = 0;
static std::unique_ptr<Temp> factory();
};
Clients that want a Temp object call the factory to build one. The factory could provide some complicated infrastructure that returns different implementations of the interface in different conditions, or something as simple as the "just give me a Temp" factory in this example.
It's possible for implementation classes to implement the interface by providing overrides for all of the pure virtual function declarations:
// in implementation.cpp:
class ConcreteTemp : public Temp {
private:
double temp;
static double tempF(double t) { return t * (9.0 / 5) + 32; }
public:
ConcreteTemp() : temp() {}
void setTemp(double t) { temp = t; }
double getTemp() const { return temp; }
double getTempF() const { return tempF(temp); }
};
and somewhere (possibly in the same implementation.cpp) we need to define the factory:
std::unique_ptr<Temp> Temp::factory() {
return std::unique_ptr<Temp>(new ConcreteTemp);
}
This approach is a little more easily extensible than pimpl: anyone who wants to can implement the Temp interface instead of there being only one "secret" implementation. There's also a bit less boilerplate since it's using the language's builtin mechanisms for virtual dispatch to dispatch interface function calls to implementations.
There is a non-orthodox approach I've seen used by pugi::xml_document from the pugixml library, and it doesn't have the overheads of pimpl or abstract classes. It goes like this:
You reserve a char array in your publicly exposed class:
class tTemp {
public:
tTemp();
~tTemp();
void setTemp(double);
double getTemp();
double getTempF();
alignas(8) char _[8]; // reserved for private use.
};
Note that
the alignment and size in this example are hardcoded. For a real application you would use an expression to estimate that based on the size of the machine word, for example sizeof(void*)*8 or similar.
adding private won't provide any additional protection because any access to _ can just as well be replaced with a cast to char*. It's the lack of implementation details in the header that provides the encapsulation.
Next, in the translation unit, you can implement tTemp as follows:
struct tTempImpl {
double temp;
};
static_assert(sizeof(tTempImpl) <= sizeof(tTemp::_), "reserved memory is too small");
static double tempF(tTemp &that) {
tTempImpl *p = (tTempImpl*)&that._[0];
return p->temp * 9 / 5 + 32;
}
tTemp::tTemp() {
tTempImpl *p = new(_) tTempImpl();
}
tTemp::~tTemp() {
((tTempImpl*)_)->~tTempImpl();
}
tTemp::tTemp(const tTemp& orig) {
new(_) tTempImpl(*(const tTempImpl*)orig._);
}
void tTemp::setTemp(double t) {
tTempImpl *p = (tTempImpl*)_;
p->temp = t;
}
double tTemp::getTemp() {
tTempImpl *p = (tTempImpl*)_;
return p->temp;
}
double tTemp::getTempF() {
return tempF(*this);
}
This is, surely, more verbose compared to other presented approaches. But this is the only zero-overhead approach I know that can truly hide all compile-time dependencies from the headers. Note that it also provides a degree of ABI stability -- you can change tTempImpl as long as its size does not exceed the reserved memory.
For a more detailed discussion about encapsulation in C++ see my True encapsulation in C++ blog post.
Private implementation (PIMPL) is the way in which C++ can provide this feature. Since I had trouble getting the unique_ptr variation to compile with CygWin g++ 4.3.4, another way to do it is to use a void * within your visible class as follows. This will allow you to use pre-C++11 compilers, and compilers like the aforementioned gcc which only had experimental support for C++11.
First, the header file ttemp.h, the one the client includes. This declares opaquely the internal implementation structure so that those internals are fully hidden. You can see that the only detail revealed is the name of the internal class and variable, neither of which need to reveal any information on how the internals work:
struct tTempImpl;
class tTemp {
public:
tTemp();
~tTemp();
tTemp (const tTemp&);
void setTemp(double);
double getTemp (void);
double getTempF (void);
private:
tTempImpl *pimpl;
};
Next, the implementation file ttemp.cpp which both declares and defines the opaque stuff, and also defines the user-visible details. Since the user never sees this code, they do not know about how it's implemented:
#include "ttemp.h"
struct tTempImpl {
double temp;
tTempImpl() { temp = 0; };
double tempF (void) { return temp * 9 / 5 + 32; };
};
tTemp::tTemp() : pimpl (new tTempImpl()) {
};
tTemp::~tTemp() {
delete pimpl;
}
tTemp::tTemp (const tTemp& orig) {
pimpl = new tTempImpl;
pimpl->temp = orig.pimpl->temp;
}
void tTemp::setTemp (double t) {
pimpl->temp = t;
}
double tTemp::getTemp (void) {
return pimpl->temp;
}
double tTemp::getTempF (void) {
return pimpl->tempF();
}
Note that the internal implementation details are not protected in any way from the visible class itself. You could define the internals as a class with accessors and mutators but it seems unnecessary since it should be tightly coupled in this case.
One word of note from above: because you're using a pointer to control the hidden aspects, the default shallow copy constructor would cause grief by having two visible objects referring to the same private member (leading to a double-delete in the destructor). So you need to (as I have) provide a deep-copy copy constructor to prevent this.
Lastly, a test program showing how the whole thing hangs together:
#include <iostream>
#include "ttemp.h"
int main (void) {
tTemp t;
std::cout << t.getTemp() << "C is " << t.getTempF() << "F\n";
return 0;
}
The output of that code being, of course:
0C is 32F

C++ similar behavior to java.lang.Enum<E> [duplicate]

It is common knowledge that built-in enums in C++ are not typesafe.
I was wondering which classes implementing typesafe enums are used out there...
I myself use the following "bicycle", but it is somewhat verbose and limited:
typesafeenum.h:
struct TypesafeEnum
{
// Construction:
public:
TypesafeEnum(): id (next_id++), name("") {}
TypesafeEnum(const std::string& n): id(next_id++), name(n) {}
// Operations:
public:
bool operator == (const TypesafeEnum& right) const;
bool operator != (const TypesafeEnum& right) const;
bool operator < (const TypesafeEnum& right) const;
std::string to_string() const { return name; }
// Implementation:
private:
static int next_id;
int id;
std::string name;
};
typesafeenum.cpp:
int TypesafeEnum::next_id = 1;
bool TypesafeEnum::operator== (const TypesafeEnum& right) const
{ return id == right.id; }
bool TypesafeEnum::operator!= (const TypesafeEnum& right) const
{ return !operator== (right); }
bool TypesafeEnum::operator< (const TypesafeEnum& right) const
{ return id < right.id; }
Usage:
class Dialog
{
...
struct Result: public TypesafeEnum
{
static const Result CANCEL("Cancel");
static const Result OK("Ok");
};
Result doModal();
...
};
const Dialog::Result Dialog::Result::OK;
const Dialog::Result Dialog::Result::CANCEL;
Addition:
I think I should have been more specific about the requirements. I'll try to summarize them:
Priority 1: Setting an enum variable to an invalid value should be impossible (a compile-time error) with no exceptions.
Priority 2: Converting an enum value to/from an int should be possible with a single explicit function/method call.
Priority 3: As compact, elegant and convenient declaration and usage as possible
Priority 4: Converting enum values to and from strings.
Priority 5: (Nice to have) Possibility to iterate over enum values.
I'm currently playing around with the Boost.Enum proposal from the Boost Vault (filename enum_rev4.6.zip). Although it was never officially submitted for inclusion into Boost, it's useable as-is. (Documentation is lacking but is made up for by clear source code and good tests.)
Boost.Enum lets you declare an enum like this:
BOOST_ENUM_VALUES(Level, const char*,
(Abort)("unrecoverable problem")
(Error)("recoverable problem")
(Alert)("unexpected behavior")
(Info) ("expected behavior")
(Trace)("normal flow of execution")
(Debug)("detailed object state listings")
)
And have it automatically expand to this:
class Level : public boost::detail::enum_base<Level, string>
{
public:
enum domain
{
Abort,
Error,
Alert,
Info,
Trace,
Debug,
};
BOOST_STATIC_CONSTANT(index_type, size = 6);
Level() {}
Level(domain index) : boost::detail::enum_base<Level, string>(index) {}
typedef boost::optional<Level> optional;
static optional get_by_name(const char* str)
{
if(strcmp(str, "Abort") == 0) return optional(Abort);
if(strcmp(str, "Error") == 0) return optional(Error);
if(strcmp(str, "Alert") == 0) return optional(Alert);
if(strcmp(str, "Info") == 0) return optional(Info);
if(strcmp(str, "Trace") == 0) return optional(Trace);
if(strcmp(str, "Debug") == 0) return optional(Debug);
return optional();
}
private:
friend class boost::detail::enum_base<Level, string>;
static const char* names(domain index)
{
switch(index)
{
case Abort: return "Abort";
case Error: return "Error";
case Alert: return "Alert";
case Info: return "Info";
case Trace: return "Trace";
case Debug: return "Debug";
default: return NULL;
}
}
typedef boost::optional<value_type> optional_value;
static optional_value values(domain index)
{
switch(index)
{
case Abort: return optional_value("unrecoverable problem");
case Error: return optional_value("recoverable problem");
case Alert: return optional_value("unexpected behavior");
case Info: return optional_value("expected behavior");
case Trace: return optional_value("normal flow of execution");
case Debug: return optional_value("detailed object state listings");
default: return optional_value();
}
}
};
It satisfies all five of the priorities which you list.
A nice compromise method is this:
struct Flintstones {
enum E {
Fred,
Barney,
Wilma
};
};
Flintstones::E fred = Flintstones::Fred;
Flintstones::E barney = Flintstones::Barney;
It's not typesafe in the same sense that your version is, but the usage is nicer than standard enums, and you can still take advantage of integer conversion when you need it.
I use C++0x typesafe enums. I use some helper template/macros that provide the to/from string functionality.
enum class Result { Ok, Cancel};
I don't. Way too much overhead for little benefit. Also, being able to caste enumerations to different data types for serialization is a very handy tool. I have never seen an instance where a "Type safe" enumeration would be worth the overhead and complexity where C++ offers a good enough implementation already.
My take is that you're inventing a problem and then fitting a solution onto it. I see no need to do an elaborate framework for an enumeration of values. If you are dedicated to having your values only be members of a certain set, you could hack up a variant of a unique set datatype.
I'm personally using an adapted version of the typesafe enum idiom. It doesn't provide all the five "requirements" that you've stated in your edit, but I strongly disagree with some of them anyway. For example, I don't see how Prio#4 (conversion of values to strings) has anything to do with type safety. Most of the time string representation of individual values should be separate from the definition of the type anyway (think i18n for a simple reason why). Prio#5 (iteratio, which is optional) is one of the nicest things I'd like to see naturally happening in enums, so I felt sad that it appears as "optional" in your request, but it seems it is better addressed via a separate iteration system such as begin/end functions or an enum_iterator, which makes them work seamlessly with STL and C++11 foreach.
OTOH this simple idiom nicely provides Prio#3 Prio#1 thanks to the fact that it mostly only wraps enums with more type information. Not to mention it is a very simple solution that for the most part doesn't require any external dependency headers, so it's pretty easy to carry around. It also has the advantage of making enumerations scoped a-la-C++11:
// This doesn't compile, and if it did it wouldn't work anyway
enum colors { salmon, .... };
enum fishes { salmon, .... };
// This, however, works seamlessly.
struct colors_def { enum type { salmon, .... }; };
struct fishes_def { enum type { salmon, .... }; };
typedef typesafe_enum<colors_def> colors;
typedef typesafe_enum<fishes_def> fishes;
The only "hole" that solution provides is that it doesn't address the fact that it doesn't prevent enums of different types (or an enum and an int) from being directly compared, because when you use values directly you force the implicit conversion to int:
if (colors::salmon == fishes::salmon) { .../* Ooops! */... }
But so far I've found such problems can be solved by simply offering a better comparison to the compiler - for example, explicitly providing an operator that compares any two different enum types, then forcing it to fail:
// I'm using backports of C++11 utilities like static_assert and enable_if
template <typename Enum1, typename Enum2>
typename enable_if< (is_enum<Enum1>::value && is_enum<Enum2>::value) && (false == is_same<Enum1,Enum2>::value) , bool >
::type operator== (Enum1, Enum2) {
static_assert (false, "Comparing enumerations of different types!");
}
Though it doesn't seem to break code so far, and it does to explicitly deal with the specific problem without doing something else, I'm not sure it such thing is a thing one "should" do (I suspect it will interfere with enums already taking part in conversion operators declared elsewhere; I'd gladly receive commentary about this).
Combining this with the above typesafe idiom gives something that is relatively close to C++11 enum class in humanibility (readability and maintainability) without having to do anything too obscure. And I have to admit it was fun to do, I had never thought to actually ask the compiler if I was dealing with enums or not...
I think the Java enum would be a good model to follow. Essentially, the Java form would look like this:
public enum Result {
OK("OK"), CANCEL("Cancel");
private final String name;
Result(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
What's interesting about the Java approach is that OK and CANCEL are immutable, singleton instances of Result (with the methods that you see). You cannot create any further instances of Result. Since they're singletons, you can compare by pointer/reference---very handy. :-)
ETA: In Java, instead of doing bitmasks by hand, instead you use an EnumSet to specify a bit set (it implements the Set interface, and works like sets---but implemented using bitmasks). Much more readable than hand-written bitmask manipulation!
I gave an answer to this here, on a different topic. It's a different style of approach which allows most of the same functionality without requiring modification to the original enum definition (and consequently allowing usage in cases where you don't define the enum). It also allows runtime range checking.
The downside of my approach is that it doesn't programmatically enforce the coupling between the enum and the helper class, so they have to be updated in parallel. It works for me, but YMMV.
I am currently writing my own typesafe enum library at https://bitbucket.org/chopsii/typesafe-enums
I am not the most experienced C++ developer ever, but I am writing this due to the shortcomings of the BOOST vault enums.
Feel free to check it out and use them yourself, but they have some (hopefully minor) usability issues, and are probably not at all cross-platform.
Please contribute if you want to. This is my first open source undertaking.
Use boost::variant!
After trying a lot of the above ideas and finding them lacking I hit upon this simple approach:
#include <iostream>
#include <boost/variant.hpp>
struct A_t {};
static const A_t A = A_t();
template <typename T>
bool isA(const T & x) { if(boost::get<A_t>(&x)) return true; return false; }
struct B_t {};
static const B_t B = B_t();
template <typename T>
bool isB(const T & x) { if(boost::get<B_t>(&x)) return true; return false; }
struct C_t {};
static const C_t C = C_t();
template <typename T>
bool isC(const T & x) { if(boost::get<C_t>(&x)) return true; return false; }
typedef boost::variant<A_t, B_t> AB;
typedef boost::variant<B_t, C_t> BC;
void ab(const AB & e)
{
if(isA(e))
std::cerr << "A!" << std::endl;
if(isB(e))
std::cerr << "B!" << std::endl;
// ERROR:
// if(isC(e))
// std::cerr << "C!" << std::endl;
// ERROR:
// if(e == 0)
// std::cerr << "B!" << std::endl;
}
void bc(const BC & e)
{
// ERROR:
// if(isA(e))
// std::cerr << "A!" << std::endl;
if(isB(e))
std::cerr << "B!" << std::endl;
if(isC(e))
std::cerr << "C!" << std::endl;
}
int main() {
AB a;
a = A;
AB b;
b = B;
ab(a);
ab(b);
ab(A);
ab(B);
// ab(C); // ERROR
// bc(A); // ERROR
bc(B);
bc(C);
}
You can probably come up with a macro to generate the boilerplate. (Let me know if you do.)
Unlike other approaches this one is actually type-safe and works with old C++. You can even make cool types like boost::variant<int, A_t, B_t, boost::none>, for example, to represent a value that could be A, B, an integer or nothing which is almost Haskell98 levels of type safety.
Downsides to be aware of:
at-least with old boost -- I'm on a system with boost 1.33 -- you are limited to 20 items in your variant; there is a work-around however
affects compile time
insane error messages -- but that's C++ for you
Update
Here, for your convenience is your typesafe-enum "library". Paste this header:
#ifndef _TYPESAFE_ENUMS_H
#define _TYPESAFE_ENUMS_H
#include <string>
#include <boost/variant.hpp>
#define ITEM(NAME, VAL) \
struct NAME##_t { \
std::string toStr() const { return std::string( #NAME ); } \
int toInt() const { return VAL; } \
}; \
static const NAME##_t NAME = NAME##_t(); \
template <typename T> \
bool is##NAME(const T & x) { if(boost::get<NAME##_t>(&x)) return true; return false; } \
class toStr_visitor: public boost::static_visitor<std::string> {
public:
template<typename T>
std::string operator()(const T & a) const {
return a.toStr();
}
};
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
inline static
std::string toStr(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> & a) {
return boost::apply_visitor(toStr_visitor(), a);
}
class toInt_visitor: public boost::static_visitor<int> {
public:
template<typename T>
int operator()(const T & a) const {
return a.toInt();
}
};
template<BOOST_VARIANT_ENUM_PARAMS(typename T)>
inline static
int toInt(const boost::variant<BOOST_VARIANT_ENUM_PARAMS(T)> & a) {
return boost::apply_visitor(toInt_visitor(), a);
}
#define ENUM(...) \
typedef boost::variant<__VA_ARGS__>
#endif
And use it like:
ITEM(A, 0);
ITEM(B, 1);
ITEM(C, 2);
ENUM(A_t, B_t) AB;
ENUM(B_t, C_t) BC;
Notice you have to say A_t instead of A in the ENUM macro which destroys some of the magic. Oh well. Also, notice there's now a toStr function and a toInt function to meet OPs requirement of simple conversion to strings and ints. The requirement I can't figure out is a way to iterate over the items. Let me know if you know how to write such a thing.
Not sure if this post is too late, but there's an article on GameDev.net which satisfies all but the 5th point (ability to iterate over enumerators):
http://www.gamedev.net/reference/snippets/features/cppstringizing/
The method described by the article allows string conversion support for existing enumerations without changing their code. If you only want support for new enumerations though, I'd go with Boost.Enum (mentioned above).

generic non-invasive cache wrapper

I'm trying create a class which adds functionality to a generic class, without directly interfacing with the wrapped class. A good example of this would be a smart pointer. Specifically, I'd like to create a wrapper which caches all the i/o for one (or any?) method invoked through the wrapper. Ideally, the cache wrapper have the following properties:
it would not require the wrapping class to be changed in any way (i.e. generic)
it would not require the wrapped class to be changed in any way (i.e. generic)
it would not change the interface or syntax for using the object significantly
For example, it would be really nice to use it like this:
CacheWrapper<NumberCruncher> crunchy;
...
// do some long and ugly calculation, caching method input/output
result = crunchy->calculate(input);
...
// no calculation, use cached result
result = crunchy->calculate(input);
although something goofy like this would be ok:
result = crunchy.dispatch (&NumberCruncher::calculate, input);
I feel like this should be possible in C++, although possibly with some syntactic gymnastics somewhere along the line.
Any ideas?
I think I have the answer you are seeking, or, at least, I almost do. It uses the dispatch style you suggested was goofy, but I think it meets the first two criteria you set forth, and more or less meets the third.
The wrapping class does not have to be modified at all.
It doesn't modify the wrapped class at all.
It only changes the syntax by introducing a dispatch function.
The basic idea is to create a template class, whose parameter is the class of the object to be wrapped, with a template dispatch method, whose parameters are the argument and return types of a member function. The dispatch method looks up the passed in member function pointer to see if it has been called before. If so, it retrieves the record of previous method arguments and calculated results to return the previously calculated value for the argument given to dispatch, or to calculate it if it is new.
Since what this wrapping class does is also called memoization, I've elected to call the template Memo because that is shorter to type than CacheWrapper and I'm starting to prefer shorter names in my old age.
#include <algorithm>
#include <map>
#include <utility>
#include <vector>
// An anonymous namespace to hold a search predicate definition. Users of
// Memo don't need to know this implementation detail, so I keep it
// anonymous. I use a predicate to search a vector of pairs instead of a
// simple map because a map requires that operator< be defined for its key
// type, and operator< isn't defined for member function pointers, but
// operator== is.
namespace {
template <typename Type1, typename Type2>
class FirstEq {
FirstType value;
public:
typedef std::pair<Type1, Type2> ArgType;
FirstEq(Type1 t) : value(t) {}
bool operator()(const ArgType& rhs) const {
return value == rhs.first;
}
};
};
template <typename T>
class Memo {
// Typedef for a member function of T. The C++ standard allows casting a
// member function of a class with one signature to a type of another
// member function of the class with a possibly different signature. You
// aren't guaranteed to be able to call the member function after
// casting, but you can use the pointer for comparisons, which is all we
// need to do.
typedef void (T::*TMemFun)(void);
typedef std::vector< std::pair<TMemFun, void*> > FuncRecords;
T memoized;
FuncRecords funcCalls;
public:
Memo(T t) : memoized(t) {}
template <typename ReturnType, typename ArgType>
ReturnType dispatch(ReturnType (T::* memFun)(ArgType), ArgType arg) {
typedef std::map<ArgType, ReturnType> Record;
// Look up memFun in the record of previously invoked member
// functions. If this is the first invocation, create a new record.
typename FuncRecords::iterator recIter =
find_if(funcCalls.begin(),
funcCalls.end(),
FirstEq<TMemFun, void*>(
reinterpret_cast<TMemFun>(memFun)));
if (recIter == funcCalls.end()) {
funcCalls.push_back(
std::make_pair(reinterpret_cast<TMemFun>(memFun),
static_cast<void*>(new Record)));
recIter = --funcCalls.end();
}
// Get the record of previous arguments and return values.
// Find the previously calculated value, or calculate it if
// necessary.
Record* rec = static_cast<Record*>(
recIter->second);
typename Record::iterator callIter = rec->lower_bound(arg);
if (callIter == rec->end() || callIter->first != arg) {
callIter = rec->insert(callIter,
std::make_pair(arg,
(memoized.*memFun)(arg)));
}
return callIter->second;
}
};
Here is a simple test showing its use:
#include <iostream>
#include <sstream>
#include "Memo.h"
using namespace std;
struct C {
int three(int x) {
cout << "Called three(" << x << ")" << endl;
return 3;
}
double square(float x) {
cout << "Called square(" << x << ")" << endl;
return x * x;
}
};
int main(void) {
C c;
Memo<C> m(c);
cout << m.dispatch(&C::three, 1) << endl;
cout << m.dispatch(&C::three, 2) << endl;
cout << m.dispatch(&C::three, 1) << endl;
cout << m.dispatch(&C::three, 2) << endl;
cout << m.dispatch(&C::square, 2.3f) << endl;
cout << m.dispatch(&C::square, 2.3f) << endl;
return 0;
}
Which produces the following output on my system (MacOS 10.4.11 using g++ 4.0.1):
Called three(1)
3
Called three(2)
3
3
3
Called square(2.3)
5.29
5.29
NOTES
This only works for methods which take 1 argument and return a result. It doesn't work for methods which take 0 arguments, or 2, or 3, or more arguments. This shouldn't be a big problem, though. You can implement overloaded versions of dispatch which take different numbers of arguments up to some reasonable max. This is what the Boost Tuple library does. They implement tuples of up to 10 elements and assume most programmers don't need more than that.
The possibility of implementing multiple overloads for dispatch is why I used the FirstEq predicate template with the find_if algorithm instead of a simple for loop search. It is a little more code for a single use, but if you are going to do a similar search multiple times, it ends up being less code overall and less chance to get one of the loops subtlely wrong.
It doesn't work for methods returning nothing, i.e. void, but if the method doesn't return anything, then you don't need to cache the result!
It doesn't work for template member functions of the wrapped class because you need to pass an actual member function pointer to dispatch, and an un-instantiated template function doesn't have a pointer (yet). There may be a way around this, but I haven't tried much yet.
I haven't done much testing of this yet, so it may have some subtle (or not-so-subtle) problems.
I don't think a completely seamless solution which satisfies all your requirements with no change in syntax at all is possible in C++. (though I'd love to be proven wrong!) Hopefully this is close enough.
When I researched this answer, I got a lot of help from this very extensive write up on implementing member function delegates in C++. Anyone who wants to learn way more than they realized was possible to know about member function pointers should give that article a good read.
I don't think this can be easily done using just a wrapper as you'll have to intercept the IO calls, so wrapping a class would put the code at the wrong layer. In essence, you want to substitute the IO code underneath the object, but you're trying to do it from the top layer. If you're thinking of the code as an onion, you're trying to modify the outer skin in order to affect something two or three layers in; IMHO that suggests the design might need a rethink.
If the class that you're trying to wrap/modify this way does allow you to pass in the stream (or whatever IO mechanism you use), then substituting that one for a caching one would be the right thing to do; in essence that would be what you'd be trying to achieve with your wrapper as well.
It looks like a simple task, assuming the "NumberCruncher" has a known interface, let's say int operator(int).
Note that you'll need to make it more complicated to support other interfaces. In order to do so, i'm adding another template parameter, an Adaptor. Adaptor should convert some interface to a known interface. Here's simple and dumb implementation with static method, which is one way to do it. Also look what Functor is.
struct Adaptor1 {
static int invoke(Cached1 & c, int input) {
return(c.foo1(input));
}
};
struct Adaptor2 {
static int invoke(Cached2 & c, int input) {
return(c.foo2(input));
}
};
template class CacheWrapper<typename T, typeneame Adaptor>
{
private:
T m_cachedObj;
std::map<int, int> m_cache;
public:
// add c'tor here
int calculate(int input) {
std::map<int, int>::const_iterator it = m_cache.find(input);
if (it != m_cache.end()) {
return(it->second);
}
int res = Adaptor::invoke(m_cachedObj, input);
m_cache[input] = res;
return(res);
}
};
I think what you need is something like a proxy / decorator (design patterns). You can use templates if you don't need the dynamic part of those patterns. The point is that you need to well define the interface that you will need.
I haven't figured out the case for handling object methods, but I think I've got a good fix for regular functions
template <typename input_t, typename output_t>
class CacheWrapper
{
public:
CacheWrapper (boost::function<output_t (input_t)> f)
: _func(f)
{}
output_t operator() (const input_t& in)
{
if (in != input_)
{
input_ = in;
output_ = _func(in);
}
return output_;
}
private:
boost::function<output_t (input_t)> _func;
input_t input_;
output_t output_;
};
Which would be used as follows:
#include <iostream>
#include "CacheWrapper.h"
double squareit(double x)
{
std::cout << "computing" << std::endl;
return x*x;
}
int main (int argc, char** argv)
{
CacheWrapper<double,double> cached_squareit(squareit);
for (int i=0; i<10; i++)
{
std::cout << cached_squareit (10) << std::endl;
}
}
Any tips on how to get this to work for objects?