在 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的模板模板参数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
我理解 b2
和 b3
的声明是错误的,因为 A::AA
不完整并且 A<int>::AA
不是模板。
我希望能够声明类似于 b2
的内容。这个想法是 A
和 B
应该都使用相同的 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;
在 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的模板模板参数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
我理解 b2
和 b3
的声明是错误的,因为 A::AA
不完整并且 A<int>::AA
不是模板。
我希望能够声明类似于 b2
的内容。这个想法是 A
和 B
应该都使用相同的 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;