Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

class composition

4 views
Skip to first unread message

er

unread,
Jan 24, 2011, 5:31:25 PM1/24/11
to
Hi,

Is there a way to define A such that if B is defined like this

struct tag1{};
struct tag2{};
struct B : A<tag1, int>, A<tag2, double>{};

then

typedef B::F<tag1>::type v1_ // v1_ == int;
typedef B::F<tag2>::type v2_; // v2_ == double

By analogy, the above is feasible for a member function, say f,

template<typename Tag, typename T> struct A{
T f(Tag){ return T(); }
};

struct B : A<tag1, int>, A<tag2, double>
{
typedef A<tag1, int> a1_; using a1_::f;
typedef A<tag2, double> a2_; using a2_::f;

};

int main () {


B b;
b.f( tag1() );
b.f( tag2() );

return 0;

}

Thanks!

Radu

unread,
Jan 24, 2011, 7:34:37 PM1/24/11
to

I might be wrong, but as far as I know you can't derive from the same
type 2 times.

Ian Collins

unread,
Jan 24, 2011, 7:45:56 PM1/24/11
to
On 01/25/11 01:34 PM, Radu wrote:
> On Jan 25, 12:31 am, er<er.ci.2...@gmail.com> wrote:
>> Hi,
>>
>> Is there a way to define A such that if B is defined like this
>>
>> struct tag1{};
>> struct tag2{};
>> struct B : A<tag1, int>, A<tag2, double>{};
>>

<snip>

> I might be wrong, but as far as I know you can't derive from the same
> type 2 times.

A<tag1, int> and A<tag2, double> are distinct types.

--
Ian Collins

Ian Collins

unread,
Jan 24, 2011, 7:53:10 PM1/24/11
to

It's not clear what you are asking. The code you posted will work.

--
Ian Collins

Larry Evans

unread,
Jan 24, 2011, 8:21:44 PM1/24/11
to
On 01/24/11 16:31, er wrote:
> Hi,
>
> Is there a way to define A such that if B is defined like this
>
> struct tag1{};
> struct tag2{};
> struct B : A<tag1, int>, A<tag2, double>{};
>
> then
>
> typedef B::F<tag1>::type v1_ // v1_ == int;
> typedef B::F<tag2>::type v2_; // v2_ == double
>
> By analogy, the above is feasible for a member function, say f,
>
> template<typename Tag, typename T> struct A{
> T f(Tag){ return T(); }
> };
>
> struct B : A<tag1, int>, A<tag2, double>
> {
> typedef A<tag1, int> a1_; using a1_::f;
> typedef A<tag2, double> a2_; using a2_::f;
>
> };
>
Yes. This technigue of overloading a function within
a class with a tag in order to select a the function in an
inheritance hierarchy was used here:


http://svn.boost.org/svn/boost/sandbox/variadic_templates/boost/composite_storage/layout/operators_one_of_maybe.hpp

The overloaded function was the static:

boost::composite_storage::layout::operators<one_of_maybe,,,,>::
push_back<HeadLayout,TailComponent>::inject(index_part,...)

Although inject is static instead of a member function, I think
it would work for member functions also. The tag in the
above call is the index_part.

HTH.

Larry


er

unread,
Jan 24, 2011, 10:01:12 PM1/24/11
to

>
> It's not clear what you are asking.  The code you posted will work.
>
> --
> Ian Collins

- What I'm asking is stated before I mention "By analogy".
- Only the second part of the code works. F is not even defined in the
first part.

Phrased differently, I want to be able to for meta-function, A::F<>,
the analogue of what I have shown for member-functions A::f<>().

er

unread,
Jan 24, 2011, 10:03:26 PM1/24/11
to

> Although inject is static instead of a member function, I think
> it would work for member functions also.  The tag in the
> above call is the index_part.
>
> HTH.
>
>   Larry

Thanks, but as noted in my previous message, I'm interested in the
meta-function, not the member-function part, the latter only serving
as an analogy. It seems your answer is geared towards the latter.

Larry Evans

unread,
Jan 25, 2011, 6:12:47 AM1/25/11
to


Your post:

http://groups.google.com/group/comp.lang.c++/msg/478fcce9739b4aa1

contained in part 1:

typedef B::F<tag1>::type v1_ // v1_ == int;
typedef B::F<tag2>::type v2_; // v2_ == double

followed by part 2:

template<typename Tag, typename T> struct A{
T f(Tag){ return T(); }
};

struct B : A<tag1, int>, A<tag2, double>
{
typedef A<tag1, int> a1_; using a1_::f;
typedef A<tag2, double> a2_; using a2_::f;

};

And the F of B::F in part 1 is the F you're referring to which is not
defined. However, I'm not sure what you're asking. Do you want A to
contained a nested F type, like:

template<typename Tag, typename T>
struct A
{

class F{
typedef T type;
}
};

such that, when B is defined as:

struct B : A<tag1, int>, A<tag2, double>
{

typedef A<tag1, int> a1_; using a1_::F;
typedef A<tag2, double> a2_; using a2_::F;

};

then:

B::F<tag1>::type would be int
B::F<tag2>::type would be double

? However, that doesn't make much sense because F is not a template,

Could you try and clarify?

-Larry

Larry Evans

unread,
Jan 25, 2011, 7:01:29 AM1/25/11
to
On 01/25/11 05:12, Larry Evans wrote:
> On 01/24/11 21:01, er wrote:
>>
>>>
>>> It's not clear what you are asking. The code you posted will work.
>>>
>>> --
>>> Ian Collins
>>
>> - What I'm asking is stated before I mention "By analogy".
>> - Only the second part of the code works. F is not even defined in the
>> first part.
>>
>> Phrased differently, I want to be able to for meta-function, A::F<>,
>> the analogue of what I have shown for member-functions A::f<>().
>
[snip]

> Could you try and clarify?
Would the attached meet your needs? it compiles with
gcc5.5.1 with the -std=gnu++0x option.
class_composition.cpp

Rui Maciel

unread,
Jan 25, 2011, 10:01:35 AM1/25/11
to
er wrote:

> Hi,
>
> Is there a way to define A such that if B is defined like this
>
> struct tag1{};
> struct tag2{};
> struct B : A<tag1, int>, A<tag2, double>{};
>
> then
>
> typedef B::F<tag1>::type v1_ // v1_ == int;
> typedef B::F<tag2>::type v2_; // v2_ == double

I believe you are looking for the C++ traits pattern

http://www.kuro5hin.org/?op=displaystory&sid=2001/3/1/72020/17594


Hope this helps,
Rui Maciel

er

unread,
Jan 25, 2011, 11:21:21 AM1/25/11
to

> then:
>
>   B::F<tag1>::type would be int
>   B::F<tag2>::type would be double
>
> ?  However, that doesn't make much sense because F is not a template,
>
> Could you try and clarify?
>
> -Larry

Thanks for following up. Yes, I want B::F<> to be a template. How to
construct it, through class composition, that is the question. Again,
I'm only giving B::f<>(), a member function, as an analogy. I was
hoping this would work

template<typename Tag,typename T>
struct A{
template<typename Tag1>
struct F : enable_if<is_same<Tag, Tag1>, T>{};
};

and within B,

using a1_::F
using a2_::F

but, of course, it would be too easy...

er

unread,
Jan 25, 2011, 11:22:22 AM1/25/11
to

> Would the attached meet your needs?  it compiles with
> gcc5.5.1 with the -std=gnu++0x option.
>
>  class_composition.cpp
> < 1KViewDownload

Thanks but clicking on either of View or Download gives

Error: Failed to load and parse template
java.io.FileNotFoundException: File name: default_err.cs
Paths searched: [ ]

Do you think you could paste the code here?

er

unread,
Jan 25, 2011, 11:25:19 AM1/25/11
to

> I believe you are looking for the C++ traits pattern
>
> http://www.kuro5hin.org/?op=displaystory&sid=2001/3/1/72020/17594
>
> Hope this helps,
> Rui Maciel

This would entail specializing on Tag? In that case, it's not what I'm
looking for, but thanks.

Larry Evans

unread,
Jan 25, 2011, 12:00:00 PM1/25/11
to
Sure. Here it is:

template<typename Tag, typename T>
struct A
{
T f(Tag){ return T(); }
};

struct tag1{};
struct tag2{};


struct B : A<tag1, int>, A<tag2, double>
{

using A<tag1,int>::f;
using A<tag2,double>::f;

template<typename Tag>
struct F
;
};

template<typename Tag>
struct B::F
{
static B b;
static Tag tag;
typedef decltype(b.f(tag)) type;
};


int main () {


B b;
B::F<tag1>::type t1=b.f( tag1() );
B::F<tag2>::type t2=b.f( tag2() );

return 0;

}

0 new messages