| Topic: |
DEVELOP > c-Plus-Plus |
| User: |
"Marco Nef" |
| Date: |
25 Jan 2008 02:05:53 AM |
| Object: |
Type specific flags in a class hierarchy |
Hi there,
I'm trying to do something like the following:
template<class TYPE> class CFlags
{
public:
VOID AddFlag(TYPE eFlag);
VOID RemoveFlag(TYPE eFlag);
};
class CClass1 : public CFlags<CClass1::EFlags>
{
public:
typedef enum EFlags
{
...
} EFlags;
};
class CClass2 : public CClass1,public CFlags<CClass2::EFlags>
{
public:
typedef enum EFlags
{
...
} EFlags;
};
I know that this cannot work because the EFlags are not known where needed.
I've tried many things, but none was a nice solution or worked at all (I
prefer a real C++ solution, which means there should be no macros).
Does anyone have an idea how to solve the following problems in a nice C++
way?
- EFlags should not be in global space
- Each class in a hierarchy may have its own flags
- The flags must be type specific
Thanks,
Marco
_____________________________
()() Marco Nef
( '.')
(")_(") http://www.shima.ch/marco/
.
|
|
| User: "Michael DOUBEZ" |
|
| Title: Re: Type specific flags in a class hierarchy |
25 Jan 2008 03:31:46 AM |
|
|
Marco Nef a écrit :
Hi there,
I'm trying to do something like the following:
template<class TYPE> class CFlags
{
public:
VOID AddFlag(TYPE eFlag);
VOID RemoveFlag(TYPE eFlag);
};
class CClass1 : public CFlags<CClass1::EFlags>
{
public:
typedef enum EFlags
{
...
} EFlags;
};
class CClass2 : public CClass1,public CFlags<CClass2::EFlags>
{
public:
typedef enum EFlags
{
...
} EFlags;
};
I know that this cannot work because the EFlags are not known where needed.
I've tried many things, but none was a nice solution or worked at all (I
prefer a real C++ solution, which means there should be no macros).
Does anyone have an idea how to solve the following problems in a nice C++
way?
- EFlags should not be in global space
- Each class in a hierarchy may have its own flags
- The flags must be type specific
If having only one kind of flags is acceptable, a simple CRTP solution is:
template<class T> class CFlags
{
typedef typename T::flags_type flags_type;
public:
VOID AddFlag(flags_type eFlag);
VOID RemoveFlag(flags_type eFlag);
};
class CClass1 : public CFlags<CClass1>
{
public:
enum EFlags1
{
...
};
typedef EFlags1 flags_type;
};
class CClass2 : public CClass1,public CFlags<CClass2>
{
public:
enum EFlags2
{
...
};
typedef EFlags2 flags_type;
};
Michael
.
|
|
|
| User: "Michael DOUBEZ" |
|
| Title: Re: Type specific flags in a class hierarchy |
25 Jan 2008 03:35:08 AM |
|
|
Michael DOUBEZ a écrit :
Marco Nef a écrit :
Hi there,
I'm trying to do something like the following:
template<class TYPE> class CFlags
{
public:
VOID AddFlag(TYPE eFlag);
VOID RemoveFlag(TYPE eFlag);
};
class CClass1 : public CFlags<CClass1::EFlags>
{
public:
typedef enum EFlags
{
...
} EFlags;
};
class CClass2 : public CClass1,public CFlags<CClass2::EFlags>
{
public:
typedef enum EFlags
{
...
} EFlags;
};
I know that this cannot work because the EFlags are not known where
needed. I've tried many things, but none was a nice solution or worked
at all (I prefer a real C++ solution, which means there should be no
macros).
Does anyone have an idea how to solve the following problems in a nice
C++ way?
- EFlags should not be in global space
- Each class in a hierarchy may have its own flags
- The flags must be type specific
If having only one kind of flags is acceptable, a simple CRTP solution is:
[garbage]
sorry. Ignore that.
Michael
.
|
|
|
|
|
| User: "Michael DOUBEZ" |
|
| Title: Re: Type specific flags in a class hierarchy |
25 Jan 2008 04:01:19 AM |
|
|
Marco Nef a écrit :
Hi there,
I'm trying to do something like the following:
template<class TYPE> class CFlags
{
public:
VOID AddFlag(TYPE eFlag);
VOID RemoveFlag(TYPE eFlag);
};
class CClass1 : public CFlags<CClass1::EFlags>
{
public:
typedef enum EFlags
{
...
} EFlags;
};
class CClass2 : public CClass1,public CFlags<CClass2::EFlags>
{
public:
typedef enum EFlags
{
...
} EFlags;
};
I know that this cannot work because the EFlags are not known where needed.
I've tried many things, but none was a nice solution or worked at all (I
prefer a real C++ solution, which means there should be no macros).
Does anyone have an idea how to solve the following problems in a nice C++
way?
- EFlags should not be in global space
- Each class in a hierarchy may have its own flags
- The flags must be type specific
Since "EFlags should not be in global space", that means you cannot use
it directly in CFlags<> instance (i.e. in member or in function
parameters), only in called function. As a consequence, the derived
class must also handle the storage of the flags storage.
The closer solution I could think of is the following:
template<class T_CRTP> class CFlags
{
public:
template<TYPE>
void AddFlag(TYPE eFlag)
{
TYPE current;
static_cast<T_CRTP>(this)->get_flags(current);
//operations
static_cast<T_CRTP*>(this)->set_flags(current);
}
template<TYPE>
void RemoveFlag(TYPE eFlag)
{
TYPE current;
static_cast<T_CRTP*>(this)->get_flags(current);
//operations
static_cast<T_CRTP*>(this)->set_flags(current);
}
};
And
class CClass1 : public CFlags<CClass1>
{
public:
enum EFlags1
{
flagA
...
};
void get_flags(EFlags1& flags);
void set_flags(EFlags1& flags);
enum EFlags2
{
flagB
...
};
void get_flags(EFlags2& flags);
void set_flags(EFlags2& flags);
};
CClass1 c1:
//Calls CFlags<CClass1>::AddFlag<CClass1::EFlags1>(CClass1::EFlags1)
c1.AddFlag(CClass1::flagA);
//Calls CFlags<CClass1>::AddFlag<CClass1::EFlags2>(CClass1::EFlags2)
c1.AddFlag(CClass1::flagB);
Michael
.
|
|
|
| User: "Marco Nef" |
|
| Title: Re: Type specific flags in a class hierarchy |
25 Jan 2008 04:04:47 AM |
|
|
"Michael DOUBEZ" <michael.doubez@free.fr> wrote in message
news:4799b100$0$17767$426a34cc@news.free.fr...
Marco Nef a écrit :
Hi there,
I'm trying to do something like the following:
template<class TYPE> class CFlags
{
public:
VOID AddFlag(TYPE eFlag);
VOID RemoveFlag(TYPE eFlag);
};
class CClass1 : public CFlags<CClass1::EFlags>
{
public:
typedef enum EFlags
{
...
} EFlags;
};
class CClass2 : public CClass1,public CFlags<CClass2::EFlags>
{
public:
typedef enum EFlags
{
...
} EFlags;
};
I know that this cannot work because the EFlags are not known where
needed. I've tried many things, but none was a nice solution or worked at
all (I prefer a real C++ solution, which means there should be no
macros).
Does anyone have an idea how to solve the following problems in a nice
C++ way?
- EFlags should not be in global space
- Each class in a hierarchy may have its own flags
- The flags must be type specific
Since "EFlags should not be in global space", that means you cannot use it
directly in CFlags<> instance (i.e. in member or in function parameters),
only in called function. As a consequence, the derived class must also
handle the storage of the flags storage.
The closer solution I could think of is the following:
template<class T_CRTP> class CFlags
{
public:
template<TYPE>
void AddFlag(TYPE eFlag)
{
TYPE current;
static_cast<T_CRTP>(this)->get_flags(current);
//operations
static_cast<T_CRTP*>(this)->set_flags(current);
}
template<TYPE>
void RemoveFlag(TYPE eFlag)
{
TYPE current;
static_cast<T_CRTP*>(this)->get_flags(current);
//operations
static_cast<T_CRTP*>(this)->set_flags(current);
}
};
And
class CClass1 : public CFlags<CClass1>
{
public:
enum EFlags1
{
flagA
...
};
void get_flags(EFlags1& flags);
void set_flags(EFlags1& flags);
enum EFlags2
{
flagB
...
};
void get_flags(EFlags2& flags);
void set_flags(EFlags2& flags);
};
CClass1 c1:
//Calls CFlags<CClass1>::AddFlag<CClass1::EFlags1>(CClass1::EFlags1)
c1.AddFlag(CClass1::flagA);
//Calls CFlags<CClass1>::AddFlag<CClass1::EFlags2>(CClass1::EFlags2)
c1.AddFlag(CClass1::flagB);
Michael
Thanks for your idea. But the problem is that there are tons of classes that
should be derived from CFlags. So it is no option to implement the storage
on each of them.
At the moment we do have a base class that is not type specific. But the
problem are collisions of flags in the hierarchy.
- Marco
.
|
|
|
| User: "Grizlyk" |
|
| Title: Re: Type specific flags in a class hierarchy |
26 Jan 2008 09:51:11 AM |
|
|
Marco Nef wrote:
- EFlags should not be in global space
- Each class in a hierarchy may have its own flags
- The flags must be type specific
You can try to replace inheritance of implementation by composition:
template<class T>
class CFlags
{
public:
void AddFlag(T::flags_type eFlag);
void RemoveFlag(T::flags_type eFlag);
};
class CClass1
{
public:
enum flags_type { a };
CFlags<CClass1> flags;
};
class CClass2: public CClass1
{
public:
enum flags_type { b };
CFlags<CClass2> flags;
};
void foo()
{
CClass2 tmp;
tmp.CClass1::flags.AddFlag( CClass1::a );
tmp.flags.AddFlag( CClass2::b );
}
Maksim A. Polyanin
http://grizlyk1.narod.ru/cpp_new
.
|
|
|
|
|
|
| User: "Pete Becker" |
|
| Title: Re: Type specific flags in a class hierarchy |
25 Jan 2008 07:51:36 AM |
|
|
On 2008-01-25 03:05:53 -0500, "Marco Nef" <maillist@shima.ch> said:
I know that this cannot work because the EFlags are not known where needed.
I've tried many things, but none was a nice solution or worked at all (I
prefer a real C++ solution, which means there should be no macros).
Last time I looked, macros were part of C++. If the goal is to add
those two members to the class, they provide a sound solution. Fancy
template tricks might work, but the time spent getting them to work
could be far better spent doing other things.
--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)
.
|
|
|
|
| User: "IsaakBegProg" |
|
| Title: Re: Type specific flags in a class hierarchy |
25 Jan 2008 06:21:03 AM |
|
|
On Jan 25, 10:05=A0am, "Marco Nef" <maill...@shima.ch> wrote:
Hi there,
I'm trying to do something like the following:
template<class TYPE> class CFlags
{
What about ...
template <class _Chk>
class AssertStatA;
template <class _Chk>
class AssertStatB;
template < template<class> class __Assert >
class _FlgController
{
protected:
template <class _Flag> void Add(_Flag _data){
__Assert<_Flag>();
cout << (int)_data << endl;
}
template <class _Flag> void Rem(_Flag _data){
__Assert<_Flag>();
cout << (int)_data << endl;
}
};
class A : public _FlgController<AssertStatA>
{
public:
typedef enum EFlag
{
E_FLAG_A =3D 0
};
public:
using _FlgController<AssertStatA>::Add;
using _FlgController<AssertStatA>::Rem;
};
template<> class AssertStatA<A::EFlag>{};
class B : public A, public _FlgController<AssertStatB>
{
public:
typedef enum EFlag
{
E_FLAG_B =3D 1
};
public:
using _FlgController<AssertStatB>::Add;
using _FlgController<AssertStatB>::Rem;
};
template<> class AssertStatB<B::EFlag>{};
for example:
A a;
B b;
a.Add(A::E_FLAG_A);
// a.Add(B::E_FLAG_B); //static assert
((A&)b).Add(A::E_FLAG_A);
b.Add(B::E_FLAG_B);
.
|
|
|
|

|
Related Articles |
|
|