开发者

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*)) {
  /* ... */
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜