2012-08-23 50 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); 
} 

现在你可以通过重载来限制对该函数的访问。