2011-12-20 65 views
1

我知道我剛纔問了一個關於這個問題,但我無法弄清楚我做錯了什麼。我已經重寫只是很小的一部分,並不能找到任何錯誤(如參考使用C++ function in parent return child與CRTP(C++)的各種錯誤

我的代碼:

#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)

+0

你應該把鱈魚如果問題不是特別長的話,直接回答問題。 – kennytm 2011-12-20 14:36:17

回答

4

你需要實現你的專門功能,因爲這個:

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

非常感謝,現在編譯。 – Asmodiel 2011-12-20 14:36:08

+0

當然,很高興提供幫助。 – 2011-12-20 14:36:27

+0

這隻爲「客戶」創建專門化;您可能想要定義泛型函數,假設您希望多個類從「實體」繼承。 – 2011-12-20 14:39:01

1

如果定義模板定義之外的類模板的成員,那麼你需要包括模板規範:

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 
}; 
+0

+1我以爲他在尋找專門的方法。 – 2011-12-20 14:45:35