无法将 CRTP 用于内部 class
Can't use CRTP for inner class
我正在尝试将 CRTP 用于多种迭代器类型的通用功能。如此处所述
内部class无法使用CRTP,所以我将基础迭代器class移出容器class,在迭代器的容器内继承。但是我还是得到了
error: invalid use of incomplete type 'class ConcreteIteratorBase<Node<int>, std::iterator_traits<Node<int>*>, std::iterator<std::forward_iterator_tag, Node<int>, long int, Node<int>*, Node<int>&> >'
错误。
这是最小的可重现示例:
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <type_traits>
#include <utility>
template <typename T>
class NotEqFromEqMixin : public T
{
public:
bool operator!=(T const & other) const
{
return !(static_cast<T const &>(*this) == other);
}
};
template <typename Iterator, typename Traits, typename StdBase>
class IteratorHelperMixin : public NotEqFromEqMixin<Iterator>, public StdBase
{
public:
using pointer = typename Traits::pointer;
using reference = typename Traits::reference;
pointer operator->()
{
return &**this;
}
};
template <typename NodeT, typename TraitsT, typename StdBaseT>
class ConcreteIteratorBase
: public IteratorHelperMixin<ConcreteIteratorBase<NodeT, TraitsT, StdBaseT>, TraitsT, StdBaseT>
{
public:
using Super = IteratorHelperMixin<ConcreteIteratorBase<NodeT, TraitsT, StdBaseT>, TraitsT, StdBaseT>;
using typename Super::pointer;
using typename Super::reference;
ConcreteIteratorBase(pointer node) : node(node) {}
reference operator*() noexcept { return *node; }
bool operator==(ConcreteIteratorBase const & other) const noexcept { return node == other.node; }
protected:
pointer node;
};
template <typename Value>
class Node
{
public:
~Node() { delete next; }
Node* next = nullptr;
Value value;
};
template <typename Value>
class List
{
public:
using NodeType = Node<Value>;
void push(Value value)
{
NodeType* newNode = new NodeType();
newNode->value = value;
newNode->next = head;
head = newNode;
}
class iterator :
public ConcreteIteratorBase<
Node<Value>,
std::iterator_traits<Node<Value>*>,
std::iterator<std::forward_iterator_tag, Node<Value>>
>
{
using Super = ConcreteIteratorBase<
Node<Value>,
std::iterator_traits<Node<Value>*>,
std::iterator<std::forward_iterator_tag, Node<Value>>
>;
public:
iterator(NodeType* ptr = nullptr) : Super(ptr){}
iterator& operator++()
{
if (this->node)
{
this->node = this->node->next;
}
return *this;
}
Value& operator*()
{
return this->node->value;
}
bool operator==(const iterator& other) const
{
return this->node == other.node;
}
};
iterator begin()
{
return iterator{head};
}
iterator end()
{
return iterator{};
}
NodeType* head = nullptr;
};
int main(int , char**)
{
List<int> list;
for (int i = 0; i < 10; ++i)
{
list.push(i);
}
for(auto & val : list)
{
std::cout << val << " ";
}
std::cout << std::endl;
return 0;
}
您的问题是您在进行循环继承时滥用了 CRTP:
ConcreteIteratorBase
-> IteratorHelperMixin<ConcreteIteratorBase, ..>
-> NotEqFromEqMixin<ConcreteIteratorBase>
-> ConcreteIteratorBase
你应该在这里放弃继承
template <typename T>
class NotEqFromEqMixin //: public T
// ^^^^^^^^^^^^
{
public:
bool operator!=(T const & other) const
{
return !(static_cast<T const &>(*this) == other);
}
};
我正在尝试将 CRTP 用于多种迭代器类型的通用功能。如此处所述
error: invalid use of incomplete type 'class ConcreteIteratorBase<Node<int>, std::iterator_traits<Node<int>*>, std::iterator<std::forward_iterator_tag, Node<int>, long int, Node<int>*, Node<int>&> >'
错误。
这是最小的可重现示例:
#include <algorithm>
#include <functional>
#include <iostream>
#include <iterator>
#include <type_traits>
#include <utility>
template <typename T>
class NotEqFromEqMixin : public T
{
public:
bool operator!=(T const & other) const
{
return !(static_cast<T const &>(*this) == other);
}
};
template <typename Iterator, typename Traits, typename StdBase>
class IteratorHelperMixin : public NotEqFromEqMixin<Iterator>, public StdBase
{
public:
using pointer = typename Traits::pointer;
using reference = typename Traits::reference;
pointer operator->()
{
return &**this;
}
};
template <typename NodeT, typename TraitsT, typename StdBaseT>
class ConcreteIteratorBase
: public IteratorHelperMixin<ConcreteIteratorBase<NodeT, TraitsT, StdBaseT>, TraitsT, StdBaseT>
{
public:
using Super = IteratorHelperMixin<ConcreteIteratorBase<NodeT, TraitsT, StdBaseT>, TraitsT, StdBaseT>;
using typename Super::pointer;
using typename Super::reference;
ConcreteIteratorBase(pointer node) : node(node) {}
reference operator*() noexcept { return *node; }
bool operator==(ConcreteIteratorBase const & other) const noexcept { return node == other.node; }
protected:
pointer node;
};
template <typename Value>
class Node
{
public:
~Node() { delete next; }
Node* next = nullptr;
Value value;
};
template <typename Value>
class List
{
public:
using NodeType = Node<Value>;
void push(Value value)
{
NodeType* newNode = new NodeType();
newNode->value = value;
newNode->next = head;
head = newNode;
}
class iterator :
public ConcreteIteratorBase<
Node<Value>,
std::iterator_traits<Node<Value>*>,
std::iterator<std::forward_iterator_tag, Node<Value>>
>
{
using Super = ConcreteIteratorBase<
Node<Value>,
std::iterator_traits<Node<Value>*>,
std::iterator<std::forward_iterator_tag, Node<Value>>
>;
public:
iterator(NodeType* ptr = nullptr) : Super(ptr){}
iterator& operator++()
{
if (this->node)
{
this->node = this->node->next;
}
return *this;
}
Value& operator*()
{
return this->node->value;
}
bool operator==(const iterator& other) const
{
return this->node == other.node;
}
};
iterator begin()
{
return iterator{head};
}
iterator end()
{
return iterator{};
}
NodeType* head = nullptr;
};
int main(int , char**)
{
List<int> list;
for (int i = 0; i < 10; ++i)
{
list.push(i);
}
for(auto & val : list)
{
std::cout << val << " ";
}
std::cout << std::endl;
return 0;
}
您的问题是您在进行循环继承时滥用了 CRTP:
ConcreteIteratorBase
-> IteratorHelperMixin<ConcreteIteratorBase, ..>
-> NotEqFromEqMixin<ConcreteIteratorBase>
-> ConcreteIteratorBase
你应该在这里放弃继承
template <typename T>
class NotEqFromEqMixin //: public T
// ^^^^^^^^^^^^
{
public:
bool operator!=(T const & other) const
{
return !(static_cast<T const &>(*this) == other);
}
};