在 C++ 中使用嵌套的 class of templated class 作为模板模板参数

Use nested class of templated class as template template parameter in C++

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

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;

现在我想添加一个嵌套的class到A并使用这个嵌套的class作为class的模板模板参数SB,像这样:

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 应该都使用相同的 class T.

我希望能够声明一些类似于 A 的 classes,并带有单独命名的子 classes。我能想到的另一个用途是 A 的多个子 classes 可以用作 B.

的模板模板参数

我看到的一个解决方法是避免在 A 的子 class 上使用单独的名称,使用 b1 声明(使用 A 作为模板B 的模板参数 S)并相应地更改 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;

我看到的另一个解决方法是将classB的模板模板参数减少为一个简单的模板参数,并通过其他方式确保相同T

还有其他的可能吗?如果是,如何?

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

这对我有用:

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,则您将无法使用类型别名。然后,您可以将 "using" 语句替换为 NestedAA 的以下定义:

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

假设您希望嵌套案例起作用,并且由于 AA 本身不是模板,您可以像这样删除 B 的第二个参数的模板:

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 声明需要额外的 'class' 才能在 g++ 5.4

上编译
template<class T, template<class T> class S>

您可以创建一个模板别名:

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

然后

B<int, innerAA> b42;

Demo