I`m writing a clone of std::unordered_map and encountered a strange error with custom allocator: somehow it cannot access a private constructor of a class even though it is declared as a friend.
The fact is, when I try to call the constructor directly from the allocator, everything works fine, but when I try to repeat the whole structure behind unordered_map and call the same methods of an allocator, an error pops up…
code:
#include <iostream>
class Chaste {
template<typename T>
friend struct TheChosenOne;
private:
int x = 0;
Chaste() = default;
Chaste(int x): x(x) {}
public:
Chaste(const Chaste&) = default;
Chaste(Chaste&&) = default;
bool operator==(const Chaste& other) const {
return x == other.x;
}
};
template<typename T>
struct TheChosenOne: public std::allocator<T> {
TheChosenOne() {}
template<typename U>
TheChosenOne(const TheChosenOne<U>&) {}
template<typename... Args>
void construct(T* p, Args&&... args) const {
new(p) T(std::forward<Args>(args)...);
//T t(std::forward<Args>(args)...);
}
void construct(std::pair<const Chaste, Chaste>* p, int a, int b) const {
new(p) std::pair<const Chaste, Chaste>(Chaste(a), Chaste(b));
}
void destroy(T* p) const {
p->~T();
}
template<typename U>
struct rebind {
using other = TheChosenOne<U>;
};
};
template<typename T, typename Alloc = std::allocator<T>>
struct list{
struct BaseNode{
BaseNode* nxt;
};
struct Node : BaseNode{
T value;
template<typename... Args>
Node(Args&&... args): value(std::forward<Args>(args)...){}
};
using alloc_type = typename std::allocator_traits<Alloc>::template rebind_alloc<Node>;
using alloc_traits = typename std::allocator_traits<alloc_type>;
alloc_type allocator;
template<typename... Args>
bool make_node(Args&&... args){
Node *new_node = alloc_traits::allocate(allocator, 1);
alloc_traits::construct(allocator, new_node, std::forward<Args>(args)...);
return new_node;
}
};
template<typename key_t, typename value_t, typename Alloc = std::allocator<key_t>>
struct umap{
using NodeType = std::pair<const key_t, value_t>;
list<NodeType, Alloc> fl;
template<typename... Args>
void emplace(Args&&... args){
auto node = fl.make_node(std::forward<Args>(args)...);
//return insert(node);
}
};
int main() {
umap<Chaste, Chaste, TheChosenOne<std::pair<const Chaste, Chaste>>> m;
m.emplace(0, 0) ;
return 0;
}
Error message:
/home/bibaboba/CLionProjects/untitled4/main.cpp:55:31: error: ‘Chaste::Chaste(int)’ is private within this context
55 | Node(Args&&... args): value(std::forward<Args>(args)...){}
New contributor
Riabov Vladimir is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.