混合显式专业化和非专业化模板

问题描述:

我是模板新手。我有一个问题,有没有办法将非特化类(或通用类)的类成员函数专门化为参数。也就是说,以下程序中的U1和U2可以是一种说法,即类型为U1的boost :: shared_ptr,而T1和T2是常规类型。混合显式专业化和非专业化模板

#include <iostream> 

template <typename T1, typename T2> 
class X { 
    public: 
    template <typename U1, typename U2> 
    void get_as(U1& source, U2& dest); 
}; 

class Y { 
}; 

template<> template<> 
void 
X<int, int>::get_as<double, double>(double& source, double& dest) { 
    std::cout << "SOURCE IS " << source << std::endl; 
    std::cout << "DESTINATION IS " << dest << std::endl; 
} 

template<> template<> 
void 
X<int, int>::get_as<shared_ptr, shared_ptr>(shared_ptr<Y>& source, shared_ptr<Y>& dest) { 
//some logic 
} 


int main() 
{ 
    double d1 = 1.0; 
    double d2 = 1.1; 
    X<int, int> x; 
    x.get_as(d1, d2); 
    shared_ptr<Y> p1(new Y()); 
    shared_ptr<Y> p2(new Y()); 
    x.get_as(p1, p2); //Would this work? 

    return 0; 
} 

我尝试阅读它,但可以清楚地了解,如果它可以或不可以做到。

+0

下面的代码将只是工作'typename'模板参数可以是任何你想要的类型。我目前没有看到这与boost :: shared_ptr有什么关系,但是如果你的'get_as'函数应该检索值,你可能需要这样的参数'void get_as(U1&source,U2&dest);' – AJG85 2012-07-11 19:28:41

+0

在上次编辑之后,由于方法名称已更改而不再具有专门化,并且会生成编译器错误。你能否澄清这个问题并描述你想要的行为? – AJG85 2012-07-11 19:38:09

您的示例中的代码将不会编译,因为您的模板参数中显示的shared_ptr不是完整的类型。为了使其工作,你可以修改这样的功能:

template<> template<> 
void 
X<int, int>::get_as<shared_ptr<Y>, shared_ptr<Y> >(shared_ptr<Y>& source, shared_ptr<Y>& dest) { 
//some logic 
} 

但这可能不是你正在寻找的普遍性。不幸的是,你不能做到以下几点:

template<> template<typename T> 
void 
X<int, int>::get_as<shared_ptr<T>, shared_ptr<T> >(shared_ptr<T>& source, shared_ptr<T>& dest) { 
//some logic 
} 

这将是一个模板类的成员函数的部分模板特化。 C++禁止这种事情。但是,在了解所有有关模板和模板专业化的知识时,经常会忘记仍然有可用的旧功能重载。您预期的那样

class Y { 
}; 

class Z { 
}; 

template <typename T1, typename T2> 
class X { 
    public: 
    template <typename U1, typename U2> 
    void get_as(U1& source, U2& dest); 

    template <typename U> 
    void get_as(shared_ptr<U> source, shared_ptr<U> dest); 

    void get_as(shared_ptr<Y> source, shared_ptr<Y> dest); 
}; 



template<> template<> 
void 
X<int, int>::get_as<double, double>(double& source, double& dest) { 
    std::cout << "SOURCE IS " << source << std::endl; 
    std::cout << "DESTINATION IS " << dest << std::endl; 
} 

template <typename T1, typename T2> 
template <typename U> 
void X<T1, T2>::get_as(shared_ptr<U> source, shared_ptr<U> dest) 
{ 
    std::cout << "Overloaded member" << std::endl; 
} 

template <typename T1, typename T2> 
void X<T1, T2>::get_as(shared_ptr<Y> source, shared_ptr<Y> dest) 
{ 
    std::cout << "Special overloaded member" << std::endl; 
} 

int main() 
{ 
    double d1 = 1.0; 
    double d2 = 1.1; 
    X<int, int> x; 
    x.get_as(d1, d2); 
    shared_ptr<Y> p1(new Y()); 
    shared_ptr<Y> p2(new Y()); 
    x.get_as(p1, p2); //Would this work? 

    shared_ptr<Z> p3(new Z()); 
    shared_ptr<Z> p4(new Z()); 
    x.get_as(p3, p4); //Would this work? 

    return 0; 
} 

输出是

SOURCE IS 1 
DESTINATION IS 1.1 
Special overloaded member 
Overloaded member