Различные ошибки с CRTP (C ++) - PullRequest
1 голос
/ 20 декабря 2011

Я знаю, что только что задал вопрос по этому поводу, но я не могу понять, что я делаю неправильно. Я переписал только небольшую часть и не могу найти никаких ошибок (использовал C ++ функцию в родительском возврате child в качестве ссылки)

Мой код:

#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;
}

Результат:

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’

Буду очень признателен за ответы (хотя моя некомпетентность может быть связана с лишением сна: D)

Ответы [ 2 ]

4 голосов
/ 20 декабря 2011

Вам необходимо реализовать свои специализированные функции следующим образом:

template<>
const string& Entity<Client>::name() const {
    return _name;
}

template<>
Client& Entity<Client>::name(const string& name) {
    _name = name;
    return *This();
}

, а также добавить публичное наследование:

class Client : public Entity<Client>

, чтобы вы могли получить доступ name().

Если вы хотите универсальные реализации:

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();
}
1 голос
/ 20 декабря 2011

Если вы определяете элементы шаблона класса вне определения шаблона, то вам необходимо включить спецификацию шаблона:

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();
}

Вам также необходимо публично наследовать от Entity:

class Client : public Entity<Client> {
    // stuff
};
...