I am trying to implement a custom std compliant container class with an iterator.
To do so, i started to define the public type definitions to be used by traits for the container class as well as the iterator.
I want to make it c++17 compliant and try to not use c++20 removed features or c++17 deprecated.
This is what i got:
template <typename T, typename Alloc = std::allocator<T>>
class container {
    using allocator_type = Alloc;
    using value_type = std::allocator_traits<Alloc>::value_type;
    using pointer = std::allocator_traits<Alloc>::pointer;
    using const_pointer = std::allocator_traits<Alloc>::const_pointer;
    using reference = value_type&; // <-- here 
    using const_reference = const value_type&; // <-- here 
    using difference_type = std::allocator_traits<Alloc>::difference_type;
    using size_type = std::allocator_traits<Alloc>::size_type;
    class iterator;
};
template <typename T, typename Alloc = std::allocator<T>>
class container::iterator {
    using value_type = std::allocator_traits<Alloc>::value_type;
    using pointer = std::allocator_traits<Alloc>::pointer;
    using const_pointer = std::allocator_traits<Alloc>::const_pointer;
    using reference = value_type&; // <-- here 
    using const_reference = const value_type&; // <-- here
    using difference_type = std::allocator_traits<Alloc>::difference_type;
    using size_type = std::allocator_traits<Alloc>::size_type;
};
Do i have to define reference and const_reference types myself like i did in the example or is there another std way of doint it?
Another question would be how to define a const_iterator without duplicating my iterator.
Some say that i should template my iterator with the value type, some just write a new iterator.
If i would template i dont know how i would create the right type traits for it, so my function definitions for the std:
reference operator*() const and pointer operator->() const,
because reference would be const_reference and const_reference would be technically const const_reference.
For example:
template <typename T>
class container {
    
    template <typename ValueType>
    class iterator;
    using iterator = iterator<T>;
    using const_iterator = iterator<const T>;
};
template <typename ValueType>
class container::iterator {
public:
    using value_type = ValueType;
    using pointer = value_type*;
    using const_pointer = const value_type*;
    using reference = value_type&;
    using const_reference = const value_type&;
    reference operator*() const;
    pointer operator->() const;
};
				
                        
Yes. The allocator doesn't know how your container is implemented, so it cannot know how to define those type aliases.
With the magic of templates.
iterator<T>vsiterator<const T>.That's not a problem as long as
const_referenceisconst T&because due to const folding rulesconst const_referenceis simplyconst T&which is what you would want.