[Код в вопросе не является ни минимальным, ни воспроизводимым.]
Проблема в том, что параметры типа cls<T>::type
не выводимы.Это именно тот шаблон, который у вас есть:
template <typename InputIterator>
Vector(typename __isInputIterator<InputIterator>::__result, typename __isInputIterator<InputIterator>::__result, const allocator &);
Вы просто должны переформулировать конструктор так, чтобы он был выводимым:
template <typename InputIterator,
typename __isInputIterator<InputIterator>::__result* = nullptr>
Vector(InputIterator, InputIterator, const allocator & = allocator{});
Таким образом, InputIterator выводим, иего достоверность проверяется параметром по умолчанию.Это все равно не будет делать то, что вы хотите, так как в вашем частичном коде __isInputIterator<InputIterator>::__result
всегда определено для чего-то.Вы хотите что-то, что является SFINAE, то есть определено, только если это входной итератор и не определено иначе.Вы хотите что-то вроде std::enable_if
:
template <typename InputIterator,
std::enable_if_t<__isInputIterator<InputIterator>::__result::value>* x = nullptr>
Vector(InputIterator, InputIterator, const allocator & = allocator{});
Общие комментарии относительно вашего кода:
- Не следует использовать имена с префиксом с двойным подчеркиванием (
__
), так какэти имена зарезервированы для компилятора. - Код слишком сложен для того, что он делает.Посмотрите на вопрос переполнения стека Как проверить, является ли произвольный тип итератором? для более коротких способов проверить, является ли тип итератором.
Это кодс минимальными изменениями, что работает.
Это ужасно, и я не буду рекомендовать его использовать .Он просто служит для заполнения пробелов в исходном вопросе:
#include <memory>
#include <type_traits>
struct InputIterator {
constexpr static bool isInputIterator {true};
//...
};
struct __falseType
{
static constexpr bool value{false};
};
struct __trueType
{
static constexpr bool value{true};
};
template <typename, bool>
struct __InputIteratorInferringAuxiliary {
using __type = __falseType;
};
template <typename Iterator>
struct __InputIteratorInferringAuxiliary<Iterator, true> {
using __type = __trueType;
};
struct NotIterator {
static constexpr bool isInputIterator = false;
};
template <typename T>
struct __IteratorTraits {
using iteratorTag = NotIterator;
};
struct RandomAccessIterator {
static constexpr bool isInputIterator = true;
};
template <typename T>
struct __IteratorTraits<T *> {
using sizeType = unsigned long;
using differenceType = long;
using valueType = T;
using reference = valueType &;
using constReference = const valueType &;
using rightValueReference = valueType &&;
using pointer = valueType *;
using constPointer = const valueType *;
using iteratorTag = RandomAccessIterator;//isInputIterator tag in RandomAccessIterator class is true
};
template <typename Iterator>
struct __isInputIterator {
using __result = typename __InputIteratorInferringAuxiliary<Iterator,
__IteratorTraits<Iterator>::iteratorTag::isInputIterator
>::__type;
};
template <class T, class allocator=std::allocator<T>>
class Vector
{
public:
template <typename InputIterator,
std::enable_if_t<__isInputIterator<InputIterator>::__result::value>* x = nullptr>
Vector(InputIterator, InputIterator, const allocator & = allocator{});
T* begin();
T* end();
};
int main()
{
int arr[] {1, 2, 3};
Vector<int> vec(std::begin(arr), std::end(arr));//candidate template ignored: couldn't infer template argument 'InputIterator'
Vector<int> vec2(1,2);//candidate template ignored: couldn't infer template argument 'InputIterator'
}