Я хочу клонировать структуру данных, содержащую std::list
нескольких типов, и одновременно перемещать некоторые итераторы, чтобы они указывали на новые элементы std::list
. Для этого я создал общий тип Translate<T>
, представляющий сопоставление std::list<T>::iterator
в старом списке с теми, что в новом списке. Затем у меня есть новый класс, наследуемый от Translate<T>
для всех необходимых типов T
моей структуры данных.
Вот упрощенный пример (с использованием только функции идентификации):
#include <list>
struct T1 {};
struct T2 {};
template<typename T>
class Translate {
public:
typename std::list<T>::iterator operator()(typename std::list<T>::iterator x) {
return x; // more complex in the real world, but doesn't matter here
}
};
int main() {
std::list<T1> l1{};
std::list<T2> l2{};
class : public Translate<T1>, public Translate<T2> {} tr;
tr(l1.begin());
}
Это дает мне следующую ошибку компилятора:
mwe.cpp: In function ‘int main()’:
mwe.cpp:19:15: error: request for member ‘operator()’ is ambiguous
tr(l1.begin());
^
mwe.cpp:9:34: note: candidates are: ‘typename std::__cxx11::list<T>::iterator Translate<T>::operator()(typename std::__cxx11::list<T>::iterator) [with T = T2; typename std::__cxx11::list<T>::iterator = std::_List_iterator<T2>]’
typename std::list<T>::iterator operator()(typename std::list<T>::iterator x) {
^~~~~~~~
mwe.cpp:9:34: note: ‘typename std::__cxx11::list<T>::iterator Translate<T>::operator()(typename std::__cxx11::list<T>::iterator) [with T = T1; typename std::__cxx11::list<T>::iterator = std::_List_iterator<T1>]’
В чем вызов двусмысленный? std::list<T>::iterator
не конвертируются друг в друга.
Это работает, если я вручную скопирую реализацию для каждого T
в дочерний класс, но это именно то, чего стараются избегать при использовании дженериков и наследования.
g++ 8.3.0
. Вы правы, с clang компилируется нормально, я об этом даже не подумал. Спасибо! - person madlaina   schedule 11.08.2020