How to use the "Curiously recurring template" pattern - c++

I'm not sure that there is allowed to ask questions like this. But I can't really understand the code which should be used in my program.
The situations is that I have to apply an earlier written class, which is design by some pattern and I have no right to change it. Unfortunately I don't know which patter it is, and neither how to use it.
(The story is about a linked list template.)
The code is something like this:
template<typename T> class LListNode {
public:
LListNode();
void setNext(T*);
...
T* next() const;
};
template<typename T> inline void LListNode<T>::setNext(T* next) {
static_cast<T*>(this)->m_next = next;
}
...
This was the node class, the next is the main list class:
template<typename T> class LList {
public:
LList();
bool isEmpty() const;
...
T* head() const;
...
void push(T*);
...
private:
T* m_head;
T* m_tail;
};
First, I tried to instantiate just the LList class with my own class as template class. But it didn't worked. Than I thought that maybe my own class (which will be stored in the List) should be inherited from the LListNode class. Thats seemed to be a good idea, but then there I got stuck.
How can I define a class which is inherited from another class, which gets the currently defined class as template parameter?
Just to make it clear:
class Foo : LListNode<Foo> {
private:
Foo* m_next;
public:
...
At this point my compiler (gcc (Ubuntu/Linaro 4.6.4-1ubuntu1~12.04) 4.6.4
) is crying:
In instantiation of 'void LListNode<T>::setPrev(T*) [with T = Foo]':
required from LListNode<T>::LListNode() [with T = Foo]'
Foo.h: required from here
LList.h: error: LListNode<Foo>' is an inaccessible base of 'Foo'

You forgot public :
class Foo : public LListNode<Foo> {
private:
Foo* m_next;
public:
...

Related

Can I create an object whose type is a nested class pointer in a template class method?

I'm trying to write a simple linked list using a template class that has a nested class which will be used as its node.
I need a method named "search", which can return a list including all the same data nodes.
template<class T>
class List {
private:
class Node {
T data;
Node* next;
...
};
List<List<T>::Node*> search(const T &) const; // the method I need
// same error to std::vector<List<T>::Node*> search(const T &) const;
void remove(const T &); // function that depend on the above method
// other class methods
};
The reason Node is a nested class is because I don't want other people to be able to access it.
The problem is, when I declare the following object
template<typename T>
void List<T>::remove(const T &val)
{
List<List<T>::Node*> ret = search(val);
// delete the nodes that has data of val
}
List<int> list; // let's say it already has some data
list.remove(2); // and delete for all nodes with data of 2
I would be told that "no declaration matches int List<T>::search(const T&) const".
Even if I use vector<List<T>::Node*>, the above template matching failure occurs, and vector also tells me that "type/value mismatch at argument 1 in template parameter list for template<class _Tp, class _Alloc> class std::vector"
I'm a beginner and this is very confusing for me. I would appreciate it if anyone could provide a solution!

Casting an object to a derived class to access protected members of parent class

I'm trying to access a protected member of a class defined and implemented by an external library. I'd like to achieve that without copying or moving the instance if possible.
Here is a simplified example. Let's say this is the code from the external library:
// some_external_library.h
class Node {
public:
static Node Create();
protected:
Node(int val) : val_(val) {}
int val_;
};
This is what I am trying to do:
// my_code.cpp
#include "some_external_library.h"
Node node = Node::Create();
int val = node.val_; // <-- This is invalid since val_ is protected.
Node class is part of some external library that I link to my program. So, I'd like to avoid modifying Node class by adding a public function or friend declaration for accessing val_. Also, I'd like to avoid creating a copy of node object or moving from it, so I'd like to avoid creating a derived class moving/copying the Node instance just to access a member field. Is it possible?
I came up with a possible solution, which worked fine for the minimal example:
// my_code.cpp
#include "some_external_library.h"
class NodeAccessor : public Node {
public:
int val() const { return val_; }
};
Node node = Node::Create();
int val = static_cast<const NodeAccessor&>(node).val();
However, I'm not sure if this is valid since node isn't an instance of NodeAccessor. Is this standard compliant? Would it cause any problems (e.g. optimizing away of val_ during compilation of the external library)?
What you do is UB.
There is one magical way to access private/protected member in C++:
The ISO C++ standard specifies that there is no access check in case of explicit template instantiations, and following code abuse of that:
template <typename Tag>
struct result
{
using type = typename Tag::type;
static type ptr;
};
template <typename Tag> typename result<Tag>::type result<Tag>::ptr;
template<typename Tag, typename Tag::type p>
struct rob : result<Tag> {
/* fill it ... */
struct filler {
filler() { result<Tag>::ptr = p; }
};
static filler filler_obj;
};
template <typename Tag, typename Tag::type p>
typename rob<Tag, p>::filler rob<Tag, p>::filler_obj;
And then
struct NodeVal { using type = int Node::*; };
template class rob<NodeVal, &Node::val_>;
and finally:
int main() {
Node node = /**/;
(node.*result<NodeVal>::ptr);
}
Demo
Yes, that can and will and should cause problems.
You are casting a thing to a type, then the thing is not of that type.
All manner of antics can ensue as a result.
There is simply no way to do what you're trying to do, and that's a good thing! Access protections are there for a reason. Work with them, not against them.

How to inherit a red black tree from a normal bst

I'm having a gigantic trouble with inheritance. I have a normal node as follows (please, ignore any typo in the code, I do not have it right now, but it compiles fine)
template<typename T>
class Node {
Node<T> *parent, *left, *right;
...//simple methods
}
then, I implement a normal BST using the node I just created:
template<typename T>
class tree {
virtual Node<T>* insert(T value);
...// other methods of tree
}
now I want to make a red black tree, but the code for it is almost the same, so I just try to override, say, insert:
template<typename T>
class rb_node : public node<T> {
int color;
...//methods to retrieve and set the color as well the constructor
}
template<typename T>
class rb_tree : public tree<T> {
Node<T> *insert(T value){
auto z = (rb_node<T>*)tree<T>::insert(value);
while(z->parent()->color() == RED)...
}
since I cast, the z->parent() is recognized as a rb_node, but the parent don't since it was constructed in the base class, so it does not have the color() method. How do I solve this problem that is killing me for almost two weeks??
Obs: if anyone need, my code is at https://github.com/dodonut/Algorithms/tree/master/Data_Structures.
I tried to override the variables of node to rb_node on constructor(but cannot cast nullptr), on the method inside rb_node to return rb_node(but the signature of base class methods is different)
One possible solution might be to have the base tree class also take an optional NodeType template argument? As in
template<typename T, typename NodeT = Node<T>>
class tree
{
...
virtual NodeT* insert(T const& value);
...
};
Then the sub-class could use its special rb_node:
template<typename T>
class rb_tree : public tree<T, rb_node<T>>
{
...
rb_node<T>* insert(T const& value) override;
...
};

How do I change a class to a template class?

I need to change the first line to : template <class T> class Node{
class Node {
private:
double data;
Node* next;
public:
Node(double);
virtual ~Node(); //for later use of polymorphismi, review the topic again
friend class Stack; // allows dStack for private member access
};
Node::Node(double data) {
this->data = data;
next = 0;
}
Node::~Node() {
}
but i am unsure of all the internal work i need to change. Do i just need to change the private data member and the public Node function?
I think what you are looking for is something along the lines of the following:
template<typename T>
class Node
{
private:
T data;
Node* next;
public:
Node(const T& d);
virtual ~Node();
// ... etc
};
Note that you will either need to implement the template class inline, in the same file, or include the implementation at the bottom of the header file.
The point is that you change your class so that it can be used for other types except double, for example int, float etc in the same way. If we think of it in more abstractly, you need to use the class for objects of type T, where T can be any of the types mentioned above (or even more).
So, in general, you need to put template <class T> (Setting it as a template class) before your class and replace double with T type.
for class declaration:
template<typename T>
class Node
for class functions implementation:
template<typename T>
Node<T>::Node()

C++ Defining a specific object type when extending a template class

I have written a short template list class defining some methods I would like to use in implementations of it. My current problem is that I am having trouble extending the generic template type and defining a specific type.
In other words, assume I have a class called MyType
List.h:
template<class T>
class List
{
public:
Node<T> *head;
Node<T> *tail;
...
}
Inside the Node class:
public:
virtual T getData();
I want to extend this class with a specific defined type MyType so that I can have getData() behave differently in the extended class MyTypeList. I am having trouble with syntax. Any help would be greatly appreciated!
class MyTypeList : public List<T>
{
...
}
You can do something like this:
struct MyTypeList : List<MyType> {
};
although it is about the same as doing:
typedef List<MyType> MyTypeList;