Here's a question about how to distinguish between fill and range constructors. The code is copied here:
template <typename T>
struct NaiveVector {
vector<T> v;
NaiveVector(size_t num, const T &val) : v(num, val) {
cout << "(int num, const T &val)" << endl;
}
template <typename InputIterator>
NaiveVector(InputIterator first, InputIterator last) : v(first, last) {
cout << "(InputIterator first, InputIterator last)" << endl;
}
};
The code above does not work as described in this question. The solution uses SFINAE to define a range constructor, as this example :
template
<
typename InputIterator
, typename = typename ::std::enable_if
<
::std::is_same
<
T &
, typename ::std::remove_const
<
decltype(*(::std::declval< InputIterator >()))
>::type
>::value
, void
>::type
>
NaiveVector(InputIterator first, InputIterator last) : v(first, last)
{
cout << "(InputIterator first, InputIterator last)" << endl;
}
This meaning of this solution compares the dereferenced type InputIteratorwith T &. If it is indeed an iterator that points to T, the comparison std::is_samewill be true and a range constructor will be selected; if it is not an iterator, the template replacement will fail, so the range constructor will be deleted, and therefore the fill constructor will be selected.
. InputIterator const_iterator (, cbegin()), const T &, const -ness std::remove_const ( ), std::is_same , .
GNU ++ STL ( ,) - . , const_iterator.
(1) , std::is_same OR, T &, const T &?
(2), , (1), , std::remove_const , , const -ness (const const) , const T &, T &.