Reputation: 83
I need to make a general Robot
which would find path on a general Surface
.
So here is my Surface
interface:
template <typename P>
class Surface {
public:
virtual int distance(const P& from, const P& to) const = 0;
virtual bool check(const vector<P>& path, const P& from, const P& to) const = 0;
virtual vector<P> lookAround(const P& at) const = 0;
};
Here I create a simple PlanarSurface
:
class PlanarSurface : public Surface<pair<int, int>> {
public:
using point_type = pair<int, int>;
int distance(const point_type& from, const point_type& to) const override {
return to.first - from.first + to.second - from.second;
}
bool check(const vector<point_type>& path,
const point_type& from,
const point_type& to) const override {
return true; // there would be the check
}
vector<point_type> lookAround(const point_type& at) const override {
vector<point_type> result;
//...
return result;
}
};
Now I create an abstract class Robot
so that every user-implemented robot would extend it:
template <typename P>
class Robot {
public:
Robot(const Surface<P>& s): surface(s) {}
vector<P> findPath(const P& from, const P& to) {
auto path = searchPath(from, to);
if (surface.check(path, from, to)) {
return path;
}
throw runtime_error("path not found or incorrect");
}
private:
virtual vector<P> searchPath(const P& from, const P& to) = 0;
protected:
const Surface<P>& surface;
};
There searchPath
private method would be responsible for custom search algorithm, defined in children of Robot
.
Suppose I have one:
template <typename P>
class MyRobot: public Robot<P> {
public:
MyRobot(Surface<P> m): Robot<P>(m) {}
private:
vector<P> searchPath(const P& from, const P& to) override {
vector<P> result;
// ...
// use one of surface's virtual methods
auto dist = this->surface.distance(from, to); // Pure virtual function called!
cout << dist << endl;
// ...
return result;
}
};
And finally the main
function:
int main(const int argc, const char **argv) {
PlanarSurface plane;
MyRobot<pair<int, int>> robot(plane);
robot.findPath({1,2}, {3,4});
return 0;
}
So the problem is that as the reference to surface
is stored in base Robot
class we can't specify it's type with some derived of Surface
class. So the type of the reference can only be Surface<P, M>
.
We need to use surface
's distance
and lookAround
methods in our search algorithm in every child of Robot
. But in Surface<P, M>
they are pure virtual. And they can be implemented only in children of Surface<P, M>
.
Help me please! Maybe I missed something obvious..
Upvotes: 3
Views: 292
Reputation: 43662
The error is here:
MyRobot(Surface<P> m) : Robot<P>(m) {}
^^^^^^^^^^^^ value
change it to accept a reference instead
MyRobot(Surface<P>& m) : Robot<P>(m) {}
Interestingly both MSVC and gcc diagnose this problem along the lines of
invalid abstract parameter
while clang doesn't even emit a warning about this (at the time of writing this post - 4.0)
Upvotes: 4