使用嵌套的模板化类作为C ++中的模板模板参数

时间:2017-03-17 11:35:54

标签: c++ templates inner-classes template-templates

在C ++中,我想在模板化的类中使用嵌套类作为模板模板参数。对于非嵌套类,模式为:

template<class T>
class A {
public:
    T a;
    // ...
};

template<class T, template<class ST> class S>
class B {
public:
    S<T> b;
    // ...
};

B<int, A> b;

现在,我想将一个嵌套类添加到A,并将此嵌套类用作类S的模板模板参数B,如下所示:

template<class T>
class A {
public:
    class AA {
    public:
        T aa;
        // ...
    };
    // ...
};

template<class T, template<class ST> class S>
class B {
public:
    S<T> b;
    // ...
};

B<int, A> b1;          // ok
B<int, A::AA> b2;      // error
B<int, A<int>::AA> b3; // error

我了解b2b3的声明是错误的,因为A::AA不完整且A<int>::AA不是模板。

我希望能够声明与b2类似的内容。我们的想法是,AB都应使用相同的类T

我希望能够使用单独命名的子类声明一些类似于A的类。我可以想到的另一个用途是A的多个子类,可以用作B的模板模板参数。

我看到的一种解决方法是避免在A的子类上使用单个名称,使用b1声明(使用A作为模板模板参数S对于B)并相应更改B的实施(即使用S::AA<T>代替S<T>):

template<class T, template<class ST> class S>
class B {
public:
    S::AA<T> b;
    // ...
};

B<int, A> b;

我看到的其他解决方法是将类B的模板模板参数缩减为简单的模板参数,并通过其他方式确保T。{/ p>

还有其他可能吗?如果是,怎么样?

修改:在class中为template添加了遗忘的B,并将模板模板参数名称更改为ST

3 个答案:

答案 0 :(得分:3)

这对我有用:

template<class T>
class A {
public:
    class AA {
    public:
        T aa;
        // ...
    };
    // ...
};

template<class T, template<class ST> class S >
class B {
public:
    S<T> b;
    // ...
};

template<class T> using NestedAA = typename A<T>::AA;

int main()
{
  B<int, NestedAA> b; // ok

  return 0;
}

如果由于任何原因您受限于C ++ 03,则输入的别名将无法使用。然后,您可以使用&#34;替换&#34;具有以下NestedAA定义的语句:

template<class T>
class NestedAA : public A<T>::AA
{
};

答案 1 :(得分:1)

假设你希望嵌套的案例有效,而且由于AA本身不是模板,你可以放弃B&#39的第二个参数的模板,如下所示:

template<class T>
class A {
public:
    class AA {
    public:
        T aa;
        // ...
    };
    // ...
};

template<class T, class S>
class B {
public:
    S b;
    // ...
};

//B<int, A> b1;          // error
B<int, A<int>::AA> b2;      // ok

PS你原来的B声明需要一个额外的课程&#39;在g ++ 5.4上编译

template<class T, template<class T> class S>

答案 2 :(得分:1)

您可以创建模板别名:

template <typename T>
using innerAA = typename A<T>::AA;

然后

B<int, innerAA> b42;