Base Class Pointer to Hold Boost Enum
Currently, I am using a type-safe enum class from Boost Vault :
Which Typesafe Enum in C++ Are You Using?
I found it is difficult to have a parent class pointer to refer to all enum class, due to Boost::enum is a template class : boost::detail::enum_base<T>
I am using void fun(const boost::any& any)
, to accept any enum class. However, I need to cast them to an enum class before I perform iteration. I cannot cast to a base class boost::detail::enum_base<T>
, as I do not have information on what T will be.
Any suggestion on how to solve this?
One of the requirement is that, the function argument must be in boost::any.
#include <iostream>
#include <boost/any.hpp>
#include "boost/enum.hpp"
// this macro
BOOST_ENUM(boolean,
(True)
(False)
)
// expands to this enum model
namespace expanded
{
class boolean : public boost::detail::enum_base<boolean>
{
public:
enum domain
{
False,
True,
};
BOOST_STATIC_CONSTANT(index_type, size = 2);
public:
boolean() {}
boolean(domain index) : boost::detail::enum_base<boolean>(index) {}
typedef boost::optional<boolean> optional;
static optional get_by_name(const char* str)
{
if(strcmp(str, "False") == 0) return optional(False);
if(strcmp(str, "True") == 0) return optional(True);
return optional();
}
private:
friend class boost::detail::enum_base<boolean>;
static const char* names(domain index)
{
BOOST_ASSERT(static_cast<index_type>(index) < size);
switch(index)
{
case False: return "False";
case True: return "True";
default: return "";
}
}
};
}
BOOST_ENUM(boolean2,
(True2)
(False2)
)
/* I want to have a function to accept any enum class. How? */
void fun(const boost::any& any)
{
/* How about boolean2 enum? How can I have a common pointer to point to enum class? */
const boolean* d = boost::any_cast<boolean *>(any);
/* I want to use unofficial boost::enum, because it allows me to iterate through enum's members. */
for (boolean::const_iterator iterator = d->begin(); iterator != d->end(); iterator++)
{
boolean x = *iterator;
std::cout<< "Iterate through enum : "<< x<< std::endl;
}
}
int main()
{
boolean b = boolean::True;
boolean2 b2 = boolean2::True2;
/* Assume until this stage, during runtime, I have no clue b is either boolean or boolean2. */
fun(&b);
/*
* Runtime error occur here.
* throw enable_current开发者_如何学Go_exception(enable_error_info(e));
*/
fun(&b2);
getchar();
}
If the access is not possible through the base class, use function templates:
template<class TE> // should be a boost enum
void fun(TE& en)
{
for (TE::const_iterator it = en.begin(); it != en.end(); ++it)
{
/* ... */
}
}
As for a common base pointer:
You can't use one the way the boost enum is defined. It doesn't have a single base class, instead it has seperate base classes per enum type and per (optional) value type.
Also, the main point of the boost enum is static type-safety - if what you're asking is meant to work on different enum types based on runtime-decisions you are using the wrong tool.
update:
If you really have that immutable requirements, you could base explicit casting on boost::any::type
, e.g. (utilizing the function template given above):
const std::type_info& ti = any.type();
if(ti == typeid(boolean*)) {
fun(*boost::any_cast<boolean*>(any));
} else if(ti == typeid(boolean2*)) {
/* ... */
}
精彩评论