c++ - 混合显式特化和非特化模板

标签 c++ templates

我是模板新手。我有一个问题,有没有一种方法可以将非专用(或通用)类型作为参数来专门化类成员函数。那就是下面程序中的U1和U2可以是U1类型的say 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;
}

我试着阅读它,但可以清楚地理解它是否可以完成。

最佳答案

您示例中的代码将无法编译,因为模板参数中出现的 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

关于c++ - 混合显式特化和非特化模板,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11439872/

相关文章:

c++ - #include <cstdatomic> "no such file"在 ubuntu 中

c++ - 迭代 utf-8 中的字符 block

c++ - 为什么这个shared_ptr vector 的定义可以通过编译器的检查呢?

php - 将 PHP 中的 $_POST 变量传递给由 exec() 函数运行的 C++ 程序

c++ - 具有共同祖先的模板参数推导

c# - P/Invoke "Protected Memory"异常/MT或/MD

c++ - 重载数组的输出运算符

C++多重继承静态函数调用歧义

c++ - C++ 连续内存中的模板化可变大小结构

c++ - 在 IsClassT<T> 中,为什么使用 "int C::*"?我对 int 类型感到困惑