2012-08-23 228 views
0

的,我想這樣做:模板成員函數(在T型)的非模板T類

class A { 
    public: 
    void f(); 
    private: 
    void g() { }; 
}; 

class B { 
    public: 
    void f(); 
    private: 
    void g() { }; 
}; 

template<typename T> 
void T::f() { 
    g(); 
} 

int main() { 
    A a; 
    B b; 
    a.f(); 
    b.f(); 
} 

但是T :: f()的不編譯。

可能的解決方法可以使F()非會員:

template<typename T> 
void f(T* t); 

或者使用CRTP:http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern

但有沒有C++的語法如上辦?我有一個大的函數f(),它的代碼由2個類A和B共享.A和B具有相同的接口,而f()使用這個接口。然而,因爲我們沒有使用運行時多態性(即虛函數),所以f()的語料庫在編譯時需要實例化兩次,一次是A,一次是B.模板完全是爲了這個目的而設計的。在我的情況下,函數f()應該是模板函數,其模板類型是* this的類型。

+0

上述(wiki)是一個完美的有效C++語法。但我看到你問了什麼,我說不,沒有做到這一點的速記。據我所知,至少在C++ 03的世界裏。 – nullpotent

+0

你想達到什麼目的?您無法將多個定義縮減爲一個「模板」定義。不過,您可以使用預處理器實現類似的效果。 –

+2

你想做什麼?沒有編寫的語法,只是一個解釋。 –

回答

1

以下是使用免費功能並保留instance.f()語法的示例。該功能需要標記爲好友才能訪問私有方法:

#include <iostream> 

namespace details 
{ 
    template<class T> 
    static void f_impl(T* _this) 
    { 
     _this->g(); 
    } 
} 

class A { 
public: 
    template<class T> friend void details::f_impl(T*); 
    void f() 
    { 
     details::f_impl(this); 
    } 
private: 
    void g() 
    { 
     std::cout << "A" << std::endl; 
    } 
}; 

class B { 
public: 
    template<class T> friend void details::f_impl(T*); 
    void f() 
    { 
     details::f_impl(this); 
    } 
private: 
    void g() 
    { 
     std::cout << "B" << std::endl; 
    } 
}; 

int main() { 
    A a; 
    B b; 
    a.f(); 
    b.f(); 
} 
2

自由功能是正確答案。無論如何,你應該比成員函數更喜歡自由函數,因爲這個原因:你擴展接口而不會侵入類。

在這種情況下,帶有無約束模板的自由函數有點難看,因爲您只需要它適用於兩種情況,而不是所有情況。你應該這樣做:

namespace detail 
{ 
    template <typename T> 
    void f(T* t) 
    { 
     // implement stuff 
    } 
} 

void f(A* x) 
{ 
    detail::f(x); 
} 

void f(B* x) 
{ 
    detail::f(x); 
} 

現在你可以通過重載來限制對該函數的訪問。