У меня есть шаблонный класс, который выполняет действие с классом, заданным в качестве аргумента шаблона. Для некоторых из моих классов я хочу «сгруппировать» функциональность в один класс, чтобы сделать его проще для вызывающего. На самом деле код выглядит примерно так (имена были изменены):
template<typename T>
class DoSomeProcessing
{
public:
process(T &t);
};
class ProcessingFrontEnd : public DoSomeProcessing<CustomerOrder>, public DoSomeProcessing<ProductionOrder>
{
};
Проблема в том, что когда я вызываю ProcessingFrontEnd :: process с CustomerOrder в качестве аргумента, компилятор жалуется на это.
Я попытался воспроизвести проблему в меньшем тестовом приложении. Это код:
#include <vector>
class X : public std::vector<char>
, public std::vector<void *>
{
};
int main(void)
{
X x;
x.push_back('c');
return 0;
}
И действительно, если это скомпилировано, компилятор Microsoft VS2010 выдает эту ошибку:
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
Я тестировал это тестовое приложение с разными типами (char + void *, double + 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) {}
};
Компилятор больше не жалуется. Таким образом, с помощью этих методов он может четко различать символ и указатель на пустоту. Почему он не может сделать это, если два метода push_back унаследованы от родителя?