类似的方法是这样做:
template<int I>
class A {};
template<int I>
class B {};
// Forward declaration.
template<typename T, typename U>
class C;
template<template<int> class TA, template<int> class TB, int I, int J>
class C<TA<I>, TB<J>> {
// J exists only to make sure integer parameters match.
static_assert((I == J), "Template parameters' integer parameters are mismatched.");
private:
TA<I> objA;
TB<I> objB;
public:
// ...
};
// ...
C<A<4>, B<4>> ca4b4; // Valid.
C<A<4>, B<16>> ca4b16; // Static assert fails.
这将允许您保证两个容器具有相同的整数参数,如果它们没有,则发出可读的错误消息。
编辑:请注意,如果您不使用两个单独的整数参数并手动检查是否相等,则尝试使用不匹配的模板模板参数创建实例将发出难以理解的“不完整类型”错误消息。
template<template<int> class TA, template<int> class TB, int I>
class C<TA<I>, TB<I>> {
// ...
};
// ...
C<A<4>, B<16>> ca4b16; // Oops.
/* Error messages:
* GCC:
* error: aggregate 'C<A<4>, B<16> > ca4b16' has incomplete type and cannot be defined
* C<A<4>, B<16>> ca4b16;
* ^
* MSVC:
* error C2079: 'ca4b16' uses undefined class 'C<T, U>'
* with
* [
* T=A<4>,
* U=B<16>
* ]
*/
这是因为实际定义只能捕获两个参数具有相同整数参数的实例,并且任何使用不匹配整数参数的情况都将退回到前向声明,这是不完整的。使用两个单独的整数参数,然后手动检查是否相等,可以让我们捕获错误的实例化,而不是让它们退回到声明中,因此我们可以将通用错误转换为实际告诉您问题所在的内容。