Reputation: 1062
I know I've just asked a question about this, but I cannot figure out what I'm doing wrong. I've rewritten just the small part and cannot find any errors (used C++ function in parent return child as reference)
My code:
#include <iostream>
#include <stdlib.h>
#include <cstring>
using namespace std;
template<class Derived>
class Entity {
private:
string _name;
public:
const string& name() const;
Derived& name( const string& );
Derived* This() { return static_cast<Derived*>(this); }
};
class Client : Entity<Client> {
private:
long int _range;
public:
const long int& range() const;
Client& range( const long int& );
};
const string& Entity::name() const {
return _name;
}
Derived& Entity::name(const string& name) {
_name = name;
return *This();
}
const long int& Client::range() const {
return _range;
}
Client& Client::range( const long int& range ) {
_range = range;
return *this;
}
int main() {
Client ().name("Buck").range(50);
return 0;
}
The result:
untitled:25: error: ‘template<class Derived> class Entity’ used without template parameters
untitled:25: error: non-member function ‘const std::string& name()’ cannot have cv-qualifier
untitled: In function ‘const std::string& name()’:
untitled:26: error: ‘_name’ was not declared in this scope
untitled: At global scope:
untitled:29: error: expected constructor, destructor, or type conversion before ‘&’ token
untitled: In function ‘int main()’:
untitled:13: error: ‘Derived& Entity<Derived>::name(const std::string&) [with Derived = Client]’ is inaccessible
untitled:44: error: within this context
untitled:44: error: ‘Entity<Client>’ is not an accessible base of ‘Client’
I'd be very grateful for answers (my incompetence might be due to sleep deprivation though :D)
Upvotes: 1
Views: 314
Reputation: 258548
You need to implement your specialized functions as this:
template<>
const string& Entity<Client>::name() const {
return _name;
}
template<>
Client& Entity<Client>::name(const string& name) {
_name = name;
return *This();
}
and also add public inheritance:
class Client : public Entity<Client>
so you can access name()
.
If you want generic implementations:
template<class x>
const string& Entity<x>::name() const {
return _name;
}
template<class x>
x& Entity<x>::name(const string& name) {
_name = name;
return *This();
}
Upvotes: 4
Reputation: 254431
If you define members of a class template outside the template definition, then you need to include the template specification:
template <class Derived>
const string& Entity<Derived>::name() const {
return _name;
}
template <class Derived>
Derived& Entity<Derived>::name(const string& name) {
_name = name;
return *This();
}
You also need to inherit publicly from Entity
:
class Client : public Entity<Client> {
// stuff
};
Upvotes: 2