473,804 Members | 3,126 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Curiously recurring template pattern

A few questions on the curiously recurring template pattern:

This page:
http://c2.com/cgi/wiki?CuriouslyRecurringTemplate

this part:
template<typena me T> struct ArithmeticType
{
T operator + (const T& other) const
{
T result(*this); // <--------- THIS LINE
result += other;
return result;
}
// etc.
};

In the above marked line, how comes that one doesn't need any type of
cast from *this to const T& ?

And if the cast is needed, what type of cast would you use?
I suppose that the reinterpret_cas t would not be portable (in theory, or
also in practice?) and anyway does not handle cases with MI, and the
dynamic_cast is slow and works only on polimorphic types, right?


Another question on this page:
http://www.informit.com/articles/art...31473&seqNum=3

At the end there is written:
----
In general, CRTP is useful to factor out implementations of interfaces
that can only be member functions (for example, constructor,
destructors, and subscript operators).
----

For the subscript I can maybe understand, but how can you do it for
constructors and destructors?
Thank you
iuweriur

Jul 22 '05 #1
15 3088
* iuweriur:
A few questions on the curiously recurring template pattern:

This page:
http://c2.com/cgi/wiki?CuriouslyRecurringTemplate

this part:
template<typena me T> struct ArithmeticType
{
T operator + (const T& other) const
{
T result(*this); // <--------- THIS LINE
result += other;
return result;
}
// etc.
};

In the above marked line, how comes that one doesn't need any type of
cast from *this to const T& ?
Presumably the intent is that class T has a public constructor that takes
an ArithmeticType< T> argument and uses dynamic_cast down to T.

I think that's ugly, and doing a downcast in ArithmeticType is also ugly.

Downcasting is what virtual functions are all about achieving in a type-
safe and efficient manner, so I'd write
template<typena me T>
class ArithmeticType
{
protected:
virtual T const& thisT() const = 0;

T operator + (const T& other) const
{
T result( thisT() );
result += other;
return result;
}
// etc.
};
And if the cast is needed, what type of cast would you use?
No cast needed; see above.

Another question on this page:
http://www.informit.com/articles/art...31473&seqNum=3

At the end there is written:
----
In general, CRTP is useful to factor out implementations of interfaces
that can only be member functions (for example, constructor,
destructors, and subscript operators).
----

For the subscript I can maybe understand, but how can you do it for
constructors and destructors?


A set of classes may have very similar constructors or constructor parts,
differing only in the concrete types involved.

Such a constructor can be factored out in a CRT base class.

For example, the CRT base class might be Window, and a typical derived
class Button, and Button might have a static function nativeWindowHan dle()
that the Window class constructor calls; see FAQ 23.4 for other techniques
to do just about the same without using the CRT pattern.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #2

"Alf P. Steinbach" <al***@start.no > wrote in message
news:40******** ******@news.ind ividual.net...
* iuweriur:
A few questions on the curiously recurring template pattern:

This page:
http://c2.com/cgi/wiki?CuriouslyRecurringTemplate

this part:
template<typena me T> struct ArithmeticType
{
T operator + (const T& other) const
{
T result(*this); // <--------- THIS LINE
result += other;
return result;
}
// etc.
};

In the above marked line, how comes that one doesn't need any type of cast from *this to const T& ?
Presumably the intent is that class T has a public constructor that

takes an ArithmeticType< T> argument and uses dynamic_cast down to T.


A static_cast should do the trick here. I think it's required in the
above example. Maybe the authors were using VC6.

Jonathan
Jul 22 '05 #3

"Jonathan Turkanis" <te******@kanga roologic.com> wrote in message
news:2l******** ****@uni-berlin.de...
A static_cast should do the trick here. I think it's required in the
above example. Maybe the authors were using VC6.


Whoops. VC6 needs the cast too.


Jul 22 '05 #4
* Jonathan Turkanis:

"Alf P. Steinbach" <al***@start.no > wrote in message
news:40******** ******@news.ind ividual.net...
* iuweriur:
A few questions on the curiously recurring template pattern:

This page:
http://c2.com/cgi/wiki?CuriouslyRecurringTemplate

this part:
template<typena me T> struct ArithmeticType
{
T operator + (const T& other) const
{
T result(*this); // <--------- THIS LINE
result += other;
return result;
}
// etc.
};

In the above marked line, how comes that one doesn't need any type of cast from *this to const T& ?


Presumably the intent is that class T has a public constructor that

takes
an ArithmeticType< T> argument and uses dynamic_cast down to T.


A static_cast should do the trick here.


Keeping in mind that no cast is needed if the scheme shown in my earlier
posting is used: no, the reason I wrote dynamic_cast, not static_cast, is
that the (presumed) constructor is public, and so cannot know what kind of
beast it's passed. Of course ArithmeticType then needs at least one
virtual function.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #5
Jonathan Turkanis wrote:
A static_cast should do the trick here. I think it's required in the
above example. Maybe the authors were using VC6.

Jonathan

Hey how can you use static_cast to downcast like this?
When the compiler compiles the ArithmeticType, *this is not guaranteed
to be of type T as far as the compiler knows

Am I wrong?
Jul 22 '05 #6
On Sat, 10 Jul 2004 03:50:56 -0500, iuweriur <iu******@hhhh. com> wrote:
Jonathan Turkanis wrote:
A static_cast should do the trick here. I think it's required in the
above example. Maybe the authors were using VC6.
Jonathan

Hey how can you use static_cast to downcast like this?
When the compiler compiles the ArithmeticType, *this is not guaranteed
to be of type T as far as the compiler knows

Am I wrong?


Isn't that the whole point of static_cast?

If the CRTP is being used correctly *this will be as base class of type T
and the static_cast will work. If CRTP is being used incorrectly then
*this will not be a base class of T and you will get a compile error.

john
Jul 22 '05 #7
* John Harrison:
On Sat, 10 Jul 2004 03:50:56 -0500, iuweriur <iu******@hhhh. com> wrote:
Jonathan Turkanis wrote:
A static_cast should do the trick here. I think it's required in the
above example. Maybe the authors were using VC6.
Jonathan

Hey how can you use static_cast to downcast like this?
When the compiler compiles the ArithmeticType, *this is not guaranteed
to be of type T as far as the compiler knows

Am I wrong?


Isn't that the whole point of static_cast?

If the CRTP is being used correctly *this will be as base class of type T
and the static_cast will work. If CRTP is being used incorrectly then
*this will not be a base class of T and you will get a compile error.


Well I'm wondering about that: how does it work with 'export'? <g/>

Okay I don't have a compiler that supports 'export' so don't know much
about it, but if it's able to compile templates separately then it
seems that the _linker_ must detect the invalid static_cast.

So, is that detection required by the standard (if so, where), and are
linkers really that smart?

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #8
Alf P. Steinbach wrote in news:40******** *******@news.in dividual.net in
comp.lang.c++:
Isn't that the whole point of static_cast?

If the CRTP is being used correctly *this will be as base class of
type T and the static_cast will work. If CRTP is being used
incorrectly then *this will not be a base class of T and you will
get a compile error.
Well I'm wondering about that: how does it work with 'export'? <g/>


What about export makes you think it won't work ?
Okay I don't have a compiler that supports 'export' so don't know much
about it, but if it's able to compile templates separately then it
seems that the _linker_ must detect the invalid static_cast.
The "compilatio n" done by export is only half the "compilatio n" that
needs to be done. A compiler that implements export must do the
second half (instantiation) at _link_ time.

So, is that detection required by the standard (if so, where), and are
linkers really that smart?


No the compiler (whenever it compiles) detects the errors:

template < typename A, typename B >
A &my_cast( B &b )
{
return static_cast< A & >( b );
}

struct base {} b;
struct derived : base {} d;

int main()
{
base &b = d;
derived &d = my_cast< derived >( b );

int &i = my_cast< int >( d ); /* <-- error */
}

If my_cast<>() were exported then the export mechanism would need to
be told sufficient information about base and derived so that it could
be instantiated, and sufficient info' about derived so it knows it can't
do the static_cast< int & >, there is no difference between the exported
code calling static_cast<>, or operator + or trying to invoke A::foo().

When the compiler instantiates the exported code it need's to
callback (if you like) to the main compile to get all the info'
about the paramiter types.

Rob.
--
http://www.victim-prime.dsl.pipex.com/
Jul 22 '05 #9
* Rob Williscroft:
Alf P. Steinbach wrote in news:40******** *******@news.in dividual.net in
comp.lang.c++:
Isn't that the whole point of static_cast?

If the CRTP is being used correctly *this will be as base class of
type T and the static_cast will work. If CRTP is being used
incorrectly then *this will not be a base class of T and you will
get a compile error.


Well I'm wondering about that: how does it work with 'export'? <g/>


What about export makes you think it won't work ?


The reason I'm wondering was given in the next paragraph, cited below:

Okay I don't have a compiler that supports 'export' so don't know much
about it, but if it's able to compile templates separately then it
seems that the _linker_ must detect the invalid static_cast.


The "compilatio n" done by export is only half the "compilatio n" that
needs to be done. A compiler that implements export must do the
second half (instantiation) at _link_ time.


By studying your answers below I think I see what's going on. It's
not instantiation at _link_ time but instantiation that uses precompiled
information. In other words, the compiler needs access to the compiled
form of the template, not just the header file -- and if that's the
case then 'export' seems to be a very limited feature.

The alternative is that the linker invokes a partial compilation, or at
least class hierarchy information, but below you answer "no" to that?

So, is that detection required by the standard (if so, where), and are
linkers really that smart?


No the compiler (whenever it compiles) detects the errors:

When the compiler instantiates the exported code it need's to
callback (if you like) to the main compile to get all the info'
about the paramiter types.


--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Jul 22 '05 #10

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

Similar topics

5
2253
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???
14
2589
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> {
4
1496
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.
4
2583
by: AndrewD | last post by:
Hey C++ folks, I created this today, just for fun. You can make object allocation for any class around 6 times faster, simply by doing the following. class MyClass : public TXpQAlloc<MyClass,N> N is a chunking factor (defaults to 10).
4
3102
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. ...
0
9575
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10564
Oralloy
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...
1
10308
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,...
0
10073
tracyyun
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...
0
9134
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
5513
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5645
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4288
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
3
2981
bsmnconsultancy
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...

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.