473,320 Members | 1,724 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

curiously recurring template pattern problem

The following code does not compile

template <class Derived>
struct X
{
typedef typename Derived::type type;
};

struct Y : public X<Y>
{
typedef int type;
};

int main()
{
}

gcc and VC++ 7 give unhelpful error messages but Comeau C++ says 'incomplete
type is not allowed' pointing at the typedef in X.

Can someone explain to my why this should be a problem? I'm presuming that
this kind of construct is difficult or impossible to compile for some
reason.

Secondly is there a way to achieve what I want, which is to let X know the
definition of a type defined in any class derived from X, by passing the
derived type as a template parameter to X (aka the curiously recurring
template pattern).

Thanks,
john
Jul 22 '05 #1
14 2542
John Harrison wrote:
The following code does not compile

template <class Derived>
struct X
{
typedef typename Derived::type type;
};

struct Y : public X<Y>
At this point, Y is incomplete, but X must be instantiated based on Y.
The compiler doesn't yet know Y::type. At least that's how I think it
works. I don't know a solution to your problem.
{
typedef int type;
};

int main()
{
}


Jul 22 '05 #2
John Harrison wrote:
The following code does not compile

template <class Derived>
struct X
{
typedef typename Derived::type type;
};

struct Y : public X<Y>
At this point, Y is incomplete, but X must be instantiated based on Y.
The compiler doesn't yet know Y::type. At least that's how I think it
works. I don't know a solution to your problem.
{
typedef int type;
};

int main()
{
}


Jul 22 '05 #3
John Harrison wrote:
[snip]
Secondly is there a way to achieve what I want, which is to let X know the
definition of a type defined in any class derived from X, by passing the
derived type as a template parameter to X (aka the curiously recurring
template pattern).

Thanks,
john

How about this:

template <class DerivedTraits, class Derived>
struct X
{
// typedef typename Derived::type type;
typedef typename DerivedTraits::type type;
};

struct YTraits {
typedef int type;
};

struct Y : public YTraits, X<YTraits, Y>
{
// typedef int type;
};
Denis
Jul 22 '05 #4
John Harrison wrote:
[snip]
Secondly is there a way to achieve what I want, which is to let X know the
definition of a type defined in any class derived from X, by passing the
derived type as a template parameter to X (aka the curiously recurring
template pattern).

Thanks,
john

How about this:

template <class DerivedTraits, class Derived>
struct X
{
// typedef typename Derived::type type;
typedef typename DerivedTraits::type type;
};

struct YTraits {
typedef int type;
};

struct Y : public YTraits, X<YTraits, Y>
{
// typedef int type;
};
Denis
Jul 22 '05 #5
"John Harrison" <jo*************@hotmail.com> wrote in message
news:c5*************@ID-196037.news.uni-berlin.de...
The following code does not compile

template <class Derived>
struct X
{
typedef typename Derived::type type;
};

struct Y : public X<Y>
{
typedef int type;
};

int main()
{
}

gcc and VC++ 7 give unhelpful error messages but Comeau C++ says 'incomplete type is not allowed' pointing at the typedef in X.
Hi John,

Interesting thing - to me it seems that this is a problem regarding the
order of how and when the template parameters are substituted and when
typedefs are resolved. However, I´m not an expert on compiler techniques so
I´d also be interested if somebody could shed some more light onto this,
please.

Can someone explain to my why this should be a problem? I'm presuming that
this kind of construct is difficult or impossible to compile for some
reason.

[SNIP]

There is a way to circumvent this (IMHO probably correct behavior) by using
templates only instead of typedefs.

template <class Derived, typename DerivedType>
struct X
{
X() {};
~X() {};
void test() { cout << typeid( type ).name() << endl; };
typedef typename DerivedType type;
};

template<typename InternalType>
struct Y : public X<Y, InternalType>
{
Y() {};
~Y() {};
};

int main()
{
Y<int> MyObj;
MyObj.test();
return 1;
}

HTH
Chris
Jul 22 '05 #6
"John Harrison" <jo*************@hotmail.com> wrote in message
news:c5*************@ID-196037.news.uni-berlin.de...
The following code does not compile

template <class Derived>
struct X
{
typedef typename Derived::type type;
};

struct Y : public X<Y>
{
typedef int type;
};

int main()
{
}

gcc and VC++ 7 give unhelpful error messages but Comeau C++ says 'incomplete type is not allowed' pointing at the typedef in X.
Hi John,

Interesting thing - to me it seems that this is a problem regarding the
order of how and when the template parameters are substituted and when
typedefs are resolved. However, I´m not an expert on compiler techniques so
I´d also be interested if somebody could shed some more light onto this,
please.

Can someone explain to my why this should be a problem? I'm presuming that
this kind of construct is difficult or impossible to compile for some
reason.

[SNIP]

There is a way to circumvent this (IMHO probably correct behavior) by using
templates only instead of typedefs.

template <class Derived, typename DerivedType>
struct X
{
X() {};
~X() {};
void test() { cout << typeid( type ).name() << endl; };
typedef typename DerivedType type;
};

template<typename InternalType>
struct Y : public X<Y, InternalType>
{
Y() {};
~Y() {};
};

int main()
{
Y<int> MyObj;
MyObj.test();
return 1;
}

HTH
Chris
Jul 22 '05 #7
Denis Remezov wrote:

John Harrison wrote:

[snip]

Secondly is there a way to achieve what I want, which is to let X know the
definition of a type defined in any class derived from X, by passing the
derived type as a template parameter to X (aka the curiously recurring
template pattern).

Thanks,
john


How about this:

template <class DerivedTraits, class Derived>
struct X
{
// typedef typename Derived::type type;
typedef typename DerivedTraits::type type;
};

struct YTraits {
typedef int type;
};

struct Y : public YTraits, X<YTraits, Y>
{
// typedef int type;
};

Denis


In other words, I meant refactoring the derived class into two parts, the
first of which does not depend on X, then using it as above. Doing so breaks
the circular dependence of the original scheme, in which X gets parsed first,
attempting to look up names to be declared in Y, which hasn't been parsed
yet because it has X as a base. A bit of a prop to the compiler here.

Denis
Jul 22 '05 #8
Denis Remezov wrote:

John Harrison wrote:

[snip]

Secondly is there a way to achieve what I want, which is to let X know the
definition of a type defined in any class derived from X, by passing the
derived type as a template parameter to X (aka the curiously recurring
template pattern).

Thanks,
john


How about this:

template <class DerivedTraits, class Derived>
struct X
{
// typedef typename Derived::type type;
typedef typename DerivedTraits::type type;
};

struct YTraits {
typedef int type;
};

struct Y : public YTraits, X<YTraits, Y>
{
// typedef int type;
};

Denis


In other words, I meant refactoring the derived class into two parts, the
first of which does not depend on X, then using it as above. Doing so breaks
the circular dependence of the original scheme, in which X gets parsed first,
attempting to look up names to be declared in Y, which hasn't been parsed
yet because it has X as a base. A bit of a prop to the compiler here.

Denis
Jul 22 '05 #9

"Chris Theis" <Ch*************@nospam.cern.ch> wrote in message
news:c5**********@sunnews.cern.ch...
"John Harrison" <jo*************@hotmail.com> wrote in message
news:c5*************@ID-196037.news.uni-berlin.de...
The following code does not compile
[SNIP]

There is a way to circumvent this (IMHO probably correct behavior) by using
templates only instead of typedefs.

template <class Derived, typename DerivedType>
struct X
{
X() {};
~X() {};
void test() { cout << typeid( type ).name() << endl; };
typedef typename DerivedType type;


I don't think you need a typename here.
};

template<typename InternalType>
struct Y : public X<Y, InternalType>


Isn't Y a class template? In that case writing public X<Y, InternalType> should
be an error.

-Sharad
Jul 22 '05 #10

"Chris Theis" <Ch*************@nospam.cern.ch> wrote in message
news:c5**********@sunnews.cern.ch...
"John Harrison" <jo*************@hotmail.com> wrote in message
news:c5*************@ID-196037.news.uni-berlin.de...
The following code does not compile
[SNIP]

There is a way to circumvent this (IMHO probably correct behavior) by using
templates only instead of typedefs.

template <class Derived, typename DerivedType>
struct X
{
X() {};
~X() {};
void test() { cout << typeid( type ).name() << endl; };
typedef typename DerivedType type;


I don't think you need a typename here.
};

template<typename InternalType>
struct Y : public X<Y, InternalType>


Isn't Y a class template? In that case writing public X<Y, InternalType> should
be an error.

-Sharad
Jul 22 '05 #11

"John Harrison" <jo*************@hotmail.com> wrote in message
news:c5*************@ID-196037.news.uni-berlin.de...
The following code does not compile
\> Can someone explain to my why this should be a problem? I'm presuming that this kind of construct is difficult or impossible to compile for some
reason.


In CRTP even though the base class depends on the derived class, it cannot do so
in a way that requires the complete type of derived to be known to the base
class.

-Sharad
Jul 22 '05 #12

"John Harrison" <jo*************@hotmail.com> wrote in message
news:c5*************@ID-196037.news.uni-berlin.de...
The following code does not compile
\> Can someone explain to my why this should be a problem? I'm presuming that this kind of construct is difficult or impossible to compile for some
reason.


In CRTP even though the base class depends on the derived class, it cannot do so
in a way that requires the complete type of derived to be known to the base
class.

-Sharad
Jul 22 '05 #13
On Wed, 7 Apr 2004 08:12:59 +0100, "John Harrison"
<jo*************@hotmail.com> wrote:
Secondly is there a way to achieve what I want, which is to let X know the
definition of a type defined in any class derived from X, by passing the
derived type as a template parameter to X (aka the curiously recurring
template pattern).


This might help:

template <class Derived, class T>
struct X
{
typedef T type;
};

struct Y : public X<Y, int>
{
};

int main()
{
}

At what point does X need to know the type of "type" though? If it
isn't required by the definition of X, but only the definition of its
members, then you shouldn't have a problem. e.g.

template <class Derived>
struct X
{
void foo()
{
typedef typename Derived::type type;
//use type
}
};

struct Y : public X<Y>
{
typedef int type;
};
Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #14
On Wed, 7 Apr 2004 08:12:59 +0100, "John Harrison"
<jo*************@hotmail.com> wrote:
Secondly is there a way to achieve what I want, which is to let X know the
definition of a type defined in any class derived from X, by passing the
derived type as a template parameter to X (aka the curiously recurring
template pattern).


This might help:

template <class Derived, class T>
struct X
{
typedef T type;
};

struct Y : public X<Y, int>
{
};

int main()
{
}

At what point does X need to know the type of "type" though? If it
isn't required by the definition of X, but only the definition of its
members, then you shouldn't have a problem. e.g.

template <class Derived>
struct X
{
void foo()
{
typedef typename Derived::type type;
//use type
}
};

struct Y : public X<Y>
{
typedef int type;
};
Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Jul 22 '05 #15

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

5
by: papi1976 | last post by:
Hello to everyone I heard about a strange thing about wich i have'nt find anything on the net or books, someone called this "Curiously recursive pattern" or a strange trick to play with...
14
by: John Harrison | last post by:
The following code does not compile template <class Derived> struct X { typedef typename Derived::type type; }; struct Y : public X<Y> {
15
by: iuweriur | last post by:
A few questions on the curiously recurring template pattern: This page: http://c2.com/cgi/wiki?CuriouslyRecurringTemplate this part: template<typename T> struct ArithmeticType { T operator...
4
by: Martin MacRobert | last post by:
Hi Gang, The following code does not compile, but I can't figure out why. The compiler complains that the CuriouslyDerivedType (CRDerived) does not publish the "value_type", yet in fact the class...
4
by: chsalvia | last post by:
The "Curiously Recurring Template Pattern" (CRTP) recently caught my attention as a nice trick which allows static polymorphism. In other words, it lets you build extensible classes without the...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
1
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
1
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.