Есть самописное подобие stl. Суть задачи - вектор пар (тоже самописные).
Проблема появилась при попытке создать вектор с парами при включении в пару std::string
. Заругалось на неоднозначность:
ошибка: call of overloaded 'copy(vector<pair<std::__cxx11::basic_string<char>, int> >::iterator, vector<pair<std::__cxx11::basic_string<char>, int> >::iterator, pair<std::__cxx11::basic_string<char>, int>*&)' is ambiguous
copy(begin(), end(), newMemory);
~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~
Заменяю copy(begin(), ...
на std::copy(begin(), ...
, и все компилируется.
Реализация алгоритма copy
скопирована справочника. Там заявлено:
The behavior of this function template is equivalent to
то есть
поведение шаблона функции эквивалентно коду, приведенному ниже
В итоге, не могу понять, что не так с алгоритмом copy
, взятым из справочника. Почему он не переваривает std::string
если заявлено, что его поведение эквивалентно std::copy
?
#include <string>
#include <algorithm>
template<class T1, class T2>
class pair
{
public:
pair() :
first(T1()),
second(T2())
{
}
pair(T1 _first, T2 _second) :
first(_first),
second(_second)
{
}
T1 first;
T2 second;
};
template<class MyInputIterator, class MyOutputIterator>
MyOutputIterator copy(MyInputIterator first, MyInputIterator last, MyOutputIterator result)
{
while (first != last) {
*result = *first;
++result; ++first;
}
return result;
}
template<class T>
class vector
{
public:
vector() : _data(nullptr), _size(0) {}
void push_back(const T &val)
{
reserve(_size + 1);
_data[_size] = val;
_size += 1;
}
void reserve(size_t n)
{
if (n > _size)
{
T *_newData = new T[_size + 1];
if (_data)
{
copy(begin(), end(), _newData); //<<< ругается здесь
delete [] _data;
}
_data = _newData;
}
}
T* begin() { return _data; }
T* end() { return _data + _size; }
private:
T *_data;
size_t _size;
};
int main()
{
vector<pair<std::string, int>> v;
v.push_back(pair<std::string, int>("qwerty", 5));
return 0;
}
P.S. Это что-то вроде тренировки на кошках (во избежание комментариев типа "зачем всё это надо, если есть stl").
Если тип аргумента функции является специализацией шаблонного класса, то в список ассоциированных пространств имен для выполнения ADL будут включены также пространства имен, ассоциированные с типами шаблонных аргументов (см. http://eel.is/c++draft/basic.lookup.argdep#2.2). В вашем случае один из шаблонных аргументов принадлежит пространству std
. Из-за этого ADL будет рассматривать std
как ассоциированное пространство имен и выполнять там поиск.
В результате ваше copy
конкурирует с std::copy
.
Либо переименуйте свою функцию, либо используйте квалифицированное имя для вызова функции: ::copy
(либо, если уж взялись, пишите свой string
:) ).
Замените название функции на какое-нибудь другое.
Из-за argument dependent lookup, при вызове copy(...)
компилятор в вашем случае находит не только вашу copy
, но и std::copy
, и не может выбрать между ними.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Пишу код под задачу со считалкой в строке и одномерным массивом с людьмиЧерез поток делю строку на слова и через while выполняю считалку один...
Можно ли считать указатели на функции одним из способов реализации статического полиморфизма?
Пытаюсь решить следующую задачу: создать пользовательскую очередь, в которой каждый элемент равен сумме предыдущих, первый элемент равен...