【发布时间】:2018-12-05 23:21:59
【问题描述】:
假设我有一个模板类base 和一个类wrapper,其中包含base 的实例化成员。我想定义类wrapper,使其依赖于模板参数包,该模板参数包简单地“传递”给base的实例化成员。
例如考虑下面的代码,它工作正常。
#include <iostream>
template <int i, int j>
struct base {
base()
{
std::cout << "i is " << i;
std::cout << " j is " << j << std::endl;
}
};
template <int... T>
struct wrapper {
base<T...> a;
};
int main()
{
wrapper<2, 3> x;
return 0;
}
事先知道base的所有模板参数都是int,我在wrapper的声明中使用了template <int...T>。这允许有限的灵活性,例如我可以为base 的模板参数定义一些默认值,而无需修改wrapper。
但是,如果base 依赖于类型和非类型模板参数的任意列表,我如何将wrapper 的模板参数传递给base?
例如,如果我知道base 的所有模板参数都可以隐式转换为int(不会丢失!),我可以在下面的程序中定义wrapper
#include <iostream>
template <int i, bool j>
struct base {
base()
{
std::cout << "i is " << i;
std::cout << " j is " << (j ? "true" : "false") << std::endl;
}
};
template <int... T>
struct wrapper {
base<T...> a;
};
int main()
{
wrapper<2, true> x;
return 0;
}
但是如果base像下面的程序一样同时依赖于类型和非类型模板参数,显然不可能简单地将wrapper的模板参数传递给base:
#include <iostream>
template <class U, int i, int j>
struct base {
base()
{
std::cout << "i is " << i;
std::cout << " j is " << j << std::endl;
}
};
template <class... T>
struct wrapper {
base<T...> a;
};
int main()
{
wrapper<int, 2, 3> x; // Error!
return 0;
}
此程序无法编译,因为编译器需要 wrapper 的类型。
有没有办法编写一个类wrapper,将其模板参数“传递”给base 类型的成员,不管它们是什么?
我们的想法是为wrapper 提供一个通用代码,如果base 的模板签名发生变化,则不需要修改它。
【问题讨论】:
-
base是否在您的控制之下?因为如果是,我们可以约束它的模板参数列表,让wrapper更容易写。 -
AFAIK 无法完成。对于每个标识符,编译器必须知道它们是类型名称还是表达式。这也是为什么你必须为依赖名称写
typename。 -
@NickyC 是的,我自己编程
base。如果可能,我希望保留扩展/更改base的灵活性,而无需更新wrapper。 -
base不要使用非类型参数,把std::integral_constant换行。 -
“有没有办法编写一个类包装器,将其模板参数“传递”给 base 类型的成员,不管它们是什么? - 没有。