【发布时间】:2012-02-01 17:51:29
【问题描述】:
我有以下类模板:
template<class T, unsigned N>
class MyClass;
其中T 是某种类型,N - 组件数。可以使用MyClass{a1, a2, a3} 初始化类,其中参数的数量等于N。
我想添加满足以下要求的MyClass 的成员函数模板(我们将其命名为foo):
- 它由另一种类型
T2(即template<class T2> void foo(..))模板化 - 它接受足够的数据来构造
MyClass<T,N>,但不能少也不能多。违反此规则会导致编译时错误。 - 它从参数的类型推导出
T2。 IE。我希望可以调用foo({a1, a2, a3})或foo(a1, a2, a3)或类似名称,而无需每次都输入<double>或MyClass<double,N>。
有没有办法实现该功能,从而满足上述要求?
我已经考虑和/或尝试过以下解决方案:
1) 显而易见的:
...
template<class T2>
void foo(MyClass<T2, N> arg);
...
a.foo({1,2,3}); //compile-time error
原则上不能工作,因为花括号初始化列表是非推导上下文,因此它们不能推导 任何 类型。太可惜了,如果能成功我会很高兴的。
2) initializer_list
原则上不能工作,因为它无法在编译时检查参数的数量。
3) 可变参数模板魔术
类似下面的函数会很简洁:
template<class...T2, class std::enable_if<sizeof...(T2) == N, int>::type = 0>
void foo(T2... args);
..
foo(1,2,3);
但是,我无法让它工作 - 仍然无法推断出 T2。也许有人知道为什么?我使用的是 GCC4.7 20120121 快照。
4) 丑陋的
基本上这与上面的相同,只是扩展为不同 N 的几个重载。我最好重新实现 MyClass 作为不同 Ns 的一组特化,而不是使用这个。
template<class T2, class std::enable_if<N == 1, int>::type = 0>
void fun(T2 a1); //if N == 1
template<class T2, ..>
void fun(T2 a1, T2 a2); //if N == 2
template<class T2, ..>
void fun(T2 a1, T2 a2, T2 a3); //if N == 3
...
【问题讨论】:
标签: c++ function parameters c++11