У меня есть шаблон, который выполняет действие над классом, задаваемым как аргумент шаблона. Для некоторых моих классов я хочу «группировать» функциональность в одном классе, чтобы облегчить вызов вызывающего. На самом деле код выглядит примерно так (имена изменены):Неоднозначный вызов, если класс наследует от 2 шаблонных родительских классов. Зачем?
template<typename T>
class DoSomeProcessing
{
public:
process(T &t);
};
class ProcessingFrontEnd : public DoSomeProcessing<CustomerOrder>, public DoSomeProcessing<ProductionOrder>
{
};
Проблема заключается в том, что, когда я называю ProcessingFrontEnd :: процесс с CustomerOrder в качестве аргумента, что компилятор жалуется на него.
Я попытался воспроизвести проблему в более мелком тестовом приложении. Это код:
#include <vector>
class X : public std::vector<char>
, public std::vector<void *>
{
};
int main(void)
{
X x;
x.push_back('c');
return 0;
}
И действительно, если это компилируется, VS2010 компилятор Microsoft дает эту ошибку:
test.cpp
test.cpp(11) : error C2385: ambiguous access of 'push_back'
could be the 'push_back' in base 'std::vector<char,std::allocator<char> >'
or could be the 'push_back' in base 'std::vector<void *,std::allocator<void *> >'
test.cpp(11) : error C3861: 'push_back': identifier not found
Я испытал это тестовое приложение с различными типами (полукокс + ничтожными *, двойной + void *) и разные аргументы в вызове ('c', 3.14), но сообщение об ошибке всегда одно и то же.
Я тестировал это с VS2005 и VS2010, но всегда получаю ту же ошибку.
Почему компилятор не может определить правильную функцию для вызова? Что делает это запутанным для компилятора? Или это просто ошибка в компиляторе Microsoft?
EDIT: Если я явно добавить 2 метода push_back в моем классе, как это:
class X : public std::vector<char>
, public std::vector<void *>
{
public:
void push_back(char c) {}
void push_back(void *p) {}
};
Компилятор не жалуется больше. Таким образом, с помощью этих методов он может четко различать символ и указатель void. Почему он не может это сделать, если два метода push_back наследуются от родителя?
Если вы не знаете, что вы делаете, inherting из StD контейнеров является плохой идеей. –
@Stephane, я знаю, но это просто для иллюстрации проблемы более простым способом. На самом деле, я наследую свой собственный шаблонный класс, а не из std-контейнеров. – Patrick
Не могли бы вы показать строку, на которую жалуется компилятор? Являются ли классы «CustomerOrder» и «ProductionOrder» несвязанными? (Ваше тестовое приложение не подходит, как указывает Стефан, стандартные контейнеры полны интересных трюков, которые обычные классы не имеют или не нуждаются, и, кроме того, указатели void и целые типы, такие как символы, слишком близки для удобных разрешение перегрузки. Лучше предоставить больше информации о реальной проблеме.) –