I am trying to implement a list container in C++, and I have problem with compiler selecting the wrong constructor overload.
The constructors are as follows:
list(size_type count, const T& value);
template<typename InputIt>
list(InputIt begin, InputIt end);
When I initialize the object in the source file, I can not prevent the compiler from selecting the second overload:
list<int> x(5, 45);
The second overload should be selected when the given arguments are iterators. However, I can't accomplish it.
EDIT: The class declaration looks like this:
template<typename T, typename Allocator = std::allocator<T>>
class list
{
public:
using value_type = T;
using pointer = T*;
using const_pointer = const T*;
using reference = T&;
using const_reference = const T&;
using move_reference = T&&; // custom
using size_type = std::size_t;
using difference_type = std::ptrdiff_t;
list(size_type count, const T& value);
template<typename InputIt>
list(InputIt begin, InputIt end);
// ...
};
The second overload should be selected when the given arguments are iterable however I can't accomplish it?
You need to SFINAE ("Substitution Failure Is Not An Error") one of the constructors (prior to C++20), so that correct constructors will be chosen.
// Constructor for iterator range
template<typename InputIt
, std::enable_if_t<
std::is_constructible_v<
T, typename std::iterator_traits<InputIt>::value_type>>* = nullptr
>
list(InputIt begin, InputIt end)
/* : contr init list */
{}
In C++20, however, just constrain the constructor for std::input_or_output_iterator
:
template<typename InputIt>
requires (std::input_or_output_iterator<InputIt>)
list(InputIt begin, InputIt end)
/* : contr init list */
{}