I need to call init(int* iNumber)
function which is derived from the base class.
BaseClass.h
#pragma once
#include "stdafx.h"
template <class T>
class BaseClass
{
public:
BaseClass() {}
virtual ~BaseClass() {}
virtual void init(T* object) = 0;
};
ChildClass.h
#pragma once
#include "BaseClass.h"
class ChildClass : public BaseClass<int>, public BaseClass<float>
{
public:
ChildClass() {}
virtual ~ChildClass() {}
};
ChildClassImpl.h
#pragma once
#include "ChildClass.h"
class ChildClassImpl : public ChildClass
{
public:
ChildClassImpl();
virtual ~ChildClassImpl();
private:
void init(int* iNumber) override;
void init(float* fNumber) override;
};
ChildClassImpl.cpp
#include "stdafx.h"
#include <iostream>
#include "ChildClassImpl.h"
ChildClassImpl::ChildClassImpl(){}
ChildClassImpl::~ChildClassImpl(){}
void ChildClassImpl::init(int* iNumber)
{
std::cout << "Integer constructor: " << *iNumber << std::endl;
}
void ChildClassImpl::init(float* fNumber)
{
std::cout << "Float constructor: " << *fNumber << std::endl;
}
MainClass
#include "stdafx.h"
#include <iostream>
#include "ChildClassImpl.h"
using namespace std;
int main()
{
ChildClass* childClass = new ChildClassImpl();
int x = 10;
childClass->init(&x);
cout << "Test" << endl;
getchar();
return 0;
}
At compile time this is gives the error
Severity Code Description Project File Line Error (active) "BaseClass<T>::init [with T=int]" is ambiguous ConsoleApplication4 d:\\Learning\\ConsoleApplication4\\ConsoleApplication4\\ConsoleApplication4.cpp 14
What am I doing wrong here? How could I fix it with minimal changes?
This code fails because C++ performs name lookup before overload resolution and access control check. That is first step would be to determine to which class scope init
belongs to. And in this case result would be ambiguous because init
could refer to either BaseClass<int>::init
or BaseClass<float>::init
. Introducing an extra using
declaration will bring both of those functions into ChildClass
scope:
class ChildClass : public BaseClass<int>, public BaseClass<float>
{
public: using BaseClass<int>::init;
public: using BaseClass<float>::init;
So name lookup will determine that init
refers to ChildClass::init
and compiler will proceed to overload resolution.
Alternatively you can perform a cast (which is definitely not as convenient):
static_cast<BaseClass<int> *>(childClass)->init(&x);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.