In my visitor pattern implementation I am trying to use a templated return type for Visitor implementation. I currently have the following implementation.
test.h
#include <string>
template <class T> class ExprVisitor;
template <class T> class Expr {
public:
virtual T Accept(ExprVisitor<T>* visitor){};
};
template <class T> class Literal : public Expr<T> {
public:
Literal(std::string value) : value_(value) {}
T Accept(ExprVisitor<T>* visitor) { return visitor->VisitLiteralExpr(this); }
std::string value_;
};
template <class T> class ExprVisitor {
public:
T VisitLiteralExpr(Expr<T>* expr);
};
test.cc
#include <iostream>
#include <string>
#include "test.h"
using std::string;
class AstPrinter : public ExprVisitor<string> {
public:
string PrintAST(Expr<string>* expr) { return expr->Accept(this); }
string VisitLiteralExpr(Expr<string>* e) {
Literal<string>* expr = reinterpret_cast<Literal<string>*>(e);
return expr->value_;
}
};
int main(int argc, char** argv) {
Expr<string>* expression = new Literal<string>("45.67");
std::cout << (new AstPrinter())->PrintAST(expression);
return 0;
}
However, the linker complains that it is unable to find the definition for ExprVisitor.
$ g++ -o test test.cc test.h
/tmp/cc2y8pdx.o: In function `Literal<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::Accept(ExprVisitor<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)':
test.cc:(.text._ZN7LiteralINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE6AcceptEP11ExprVisitorIS5_E[_ZN7LiteralINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE6AcceptEP11ExprVisitorIS5_E]+0x27): undefined reference to `ExprVisitor<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >::VisitLiteralExpr(Expr<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >*)'
collect2: error: ld returned 1 exit status
Can I get some help in understanding what the issue is here?
Aucun commentaire:
Enregistrer un commentaire