【问题标题】:C++ : How to specialize a member function for a template Array-like class A to deal with A<A<T> >?C++:如何专门化模板类 A 类的成员函数来处理 A<A<T>>?
【发布时间】:2013-10-01 22:19:11
【问题描述】:

我正在写一个模板&lt;class T&gt;类似数组的A类,我想专门化几个成员函数来处理数组A&lt;A&lt;T&gt;&gt;的数组。

这是一个接近我想要的工作示例:

#include "stdio.h"

//primary template class 
template <class T> class A {
public: void f() {printf("A<T>::f\n");}
};

//1st solution : specialization (?) of A for A<A<T>>
template <class T> class A< A<T> > {
public: void f() {printf("A<A<T>>::f\n");}
};

//2nd solution : specialization of A::f for A<A<int>>
template<> void A< A<int> >::f() {
    printf("A<A<int>>::f\n");
}

int main(void) {

    A<int> A_int;
    A< A<int> > A_A_int;
    A< A<double> > A_A_double;

    A_int.f();        // ok : prints A<T>::f
    A_A_int.f();      // ok : prints A<A<int>>::f
    A_A_double.f();   // ok : prints A<A<T>>::f

    return 0;
}

第一个解决方案的问题是我必须从主模板类中复制很多成员函数

我试图从主类派生,但是

template <class T> class A< A<T> > : public A< A<T> >

没有意义

第二个解决方案的问题是我必须为每种可能的类型复制专业化,这违背了模板类的目的。

由于可以定义template&lt;&gt; void A&lt; A&lt;int&gt; &gt;::f(),因此似乎应该能够为任何类型“模板化”这种专门化。我试过了:

template <class T> template<> void A< A<T> >::f()
template <template <class T> > void A< A<T> >::f()
template <template <> class T> void A< A<T> >::f()

和其他荒谬的语法......

所以...我可以将专业化 template&lt;&gt; void A&lt; A&lt;int&gt; &gt;::f() 模板化,不仅适用于 int ,而且适用于任何类型 T ?

提前致谢,

最好的问候,

【问题讨论】:

  • 类模板的成员函数本身就是函数模板,当然你不能部分特化函数模板。但是,您可以将模板的公共部分分解为基类,并且只更改专业化中可修改的部分。

标签: c++ templates containers specialization


【解决方案1】:

一种可能的方式:

#include <cstdio>

// forward declaration
template<typename>
class A;

template<typename>
class A_Base {
    // general case
    public: void f() { printf("A<T>::f\n"); }
};

// partial specialization for any A
template<typename T>
class A_Base< A<T> > {
    // special stuff
    public: void f() { printf("A<A<T>>::f\n"); }
};

template<typename T>
class A : private A_Base<T> { // private inheritance, we're not modeling IS-A
public:
    using A_Base<T>::f;  // make f accesible

    // all the other stuff that doesn't need to change
};

int main()
{
    A<int> a1;
    A<A<int>> a2;
    a1.f();       // A<T>::f
    a2.f();       // A<A<T>>::f
}

这样你只把需要表现不同的函数放在基类中。你当然可以反过来——你把通用代码放在基类中,然后专门化一个派生类,你还可以在其中定义f

【讨论】:

  • “常见的东西”应该是“一般情况”吗?
  • @KerrekSB 听起来确实更好
  • 我认为您甚至可以从A_Base&lt;T&gt; 递归派生A_Base&lt; A&lt;T&gt; &gt; 以提供通用的f 函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-20
  • 1970-01-01
  • 1970-01-01
  • 2021-06-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多