Is the curiosly recurring template pattern recursive?

Feb 4, 2022 at 12:53pm
Hi,

In this definition:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
template<typename T>
struct ordered
{
	bool operator>(T const& rhs) const
	{
		// locate full derived object
		T const& self = static_cast<T const&>(*this);
		return rhs < self;
	}
};


class Int : public ordered<Int>
{
public:
        explicit Int(int value)
		: value(value)
	{
	}
	bool operator<(Int const& rhs) const
	{
		return this->value < rhs.value;
	}

	int value;
};


is the definition for Int recursive?? Int is expressed in terms of itself...
moreover by inheritance laws, Int IS-A kind of ordered<Int>, but then Int can be subsituted by its superclass so Int definition is recursive?


Please clarify
Thanks
Juan
Feb 4, 2022 at 1:06pm
It is recursive in the same sense that the definition of (a node) of a linked list is recursive.

1
2
3
4
5
struct node
{
      T value ;
      node* next ; // node is an incomplete type at this point
};


In the same way, in the definition of the base class ordered<T> (parsed during phase one of the two phase compilation model) does not require that the type T must be a completely defined type.
Feb 4, 2022 at 4:39pm
Ok... is this code an error in view of the code on my last post?

1
2
3
4
5
6
7
8
9
10
11
12
class bogus : public ordered<Int>
{
public:
	bogus(int val) : value(val) {}

private:
	int value;
};

void useInt()
{
     bool ok = bogus(2) > Int(5);	// should crash but it does not!! 


The reason I believe it should crash is the static_cast in:

1
2
3
4
5
6
7
template <typename T>
bool ordered<T>::operator>(T const& rhs) const
{
	// locate full derived object
	T const& self = static_cast<T const&>(*this);   // this here! is it suspicious??
	return rhs < self;
}


This was taken from a book and its author says it should crash, but it does not and I don't see why it should??

Thanks,
Juan
Last edited on Feb 4, 2022 at 5:06pm
Feb 5, 2022 at 3:10am
> its author says it should crash
¿as in «if this crashed, it would be great»?
https://www.cplusplus.com/doc/tutorial/typecasting/#static_cast
No checks are performed during runtime to guarantee that the object being converted is in fact a full object of the destination type. Therefore, it is up to the programmer to ensure that the conversion is safe.


you defined bogus as a kind of ordered<Int>
class bogus : public ordered<Int>
so it can match this function
ordered<Int>::operator>(Int const&) const
Last edited on Feb 5, 2022 at 3:19am
Feb 5, 2022 at 1:16pm
@ne555:

so it it does not crash because it matches the inherited function operator> ? So everything is fine?

In this code the cast is always valid??

And the author is incorrect...

can you confirm this please?
Last edited on Feb 5, 2022 at 3:03pm
Feb 7, 2022 at 5:29pm
no, it does compiles because of your weird bogus -> ordered<Int> inheritance
it's not fine, the code is awful

> In this code the cast is always valid??
don't know and don't care
it's a bad cast because the target class is not what it should
Topic archived. No new replies allowed.