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 14 2571
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() { }
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() { }
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
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
"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<typena me InternalType>
struct Y : public X<Y, InternalType>
{
Y() {};
~Y() {};
};
int main()
{
Y<int> MyObj;
MyObj.test();
return 1;
}
HTH
Chris
"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<typena me InternalType>
struct Y : public X<Y, InternalType>
{
Y() {};
~Y() {};
};
int main()
{
Y<int> MyObj;
MyObj.test();
return 1;
}
HTH
Chris
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
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
"Chris Theis" <Ch************ *@nospam.cern.c h> 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<typena me 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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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 templates and inheritance...
Dunno what is that or how it works :(
Does someone has any idea about this thing???
|
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>
{
|
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 + (const T& other) const
{
|
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 CRDerived does.
Is there any way of making the code work? I would like functions to
accept a CRBase template, and the CRBase must be able to deduce the
"value_type" of the function that it is "curiously calling".
Thanks.
|
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 overhead of
virtual function calls. (But of course, with the limitation of
compile-time resolving.)
Basically, you create a templated Base Class which defines an
interface function that uses a static_cast to call a member function
in Derived. ...
| |
by: marktang |
last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look !
Part I. Meaning of...
|
by: Oralloy |
last post by:
Hello folks,
I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>".
The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed.
This is as boiled down as I can make it.
Here is my compilation command:
g++-12 -std=c++20 -Wnarrowing bit_field.cpp
Here is the code in...
|
by: jinu1996 |
last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth.
The Art of Business Website Design
Your website is...
|
by: Hystou |
last post by:
Overview:
Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
|
by: tracyyun |
last post by:
Dear forum friends,
With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
|
by: isladogs |
last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 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 a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules.
He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms.
Adolph will...
| |
by: 6302768590 |
last post by:
Hai team
i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
|
by: muto222 |
last post by:
How can i add a mobile payment intergratation into php mysql website.
|
by: bsmnconsultancy |
last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...
| |