p12*_*p12 12 c++ parameters function c++11
我有以下类模板:
template<class T, unsigned N>
class MyClass;
Run Code Online (Sandbox Code Playgroud)
其中T是某种类型的,N-多个组件.可以使用MyClass{a1, a2, a3}参数数量等于的位置初始化类N.
我想添加一个符合以下要求的成员函数模板(让我们命名foo)MyClass:
T2(即template<class T2> void foo(..))MyClass<T,N>,但不是更少而不是更多.违反此规则会导致编译时错误.T2从参数的类型推导出来.即我想要无需打字或每次都可以打电话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
Run Code Online (Sandbox Code Playgroud)
原则上不能工作,因为支撑的初始化列表是非推导的上下文,因此它们不能推导出任何类型.这很不幸,如果有效,我会很高兴.
2)initializer_list
原则上不能工作,因为它无法在编译时检查参数的数量.
3)Variadic模板魔术
像下面的功能一样整洁:
template<class...T2, class std::enable_if<sizeof...(T2) == N, int>::type = 0>
void foo(T2... args);
..
foo(1,2,3);
Run Code Online (Sandbox Code Playgroud)
但是,我无法让它工作 - 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
...
Run Code Online (Sandbox Code Playgroud)
ken*_*ytm 10
为什么不用static_assert?
template <typename T, size_t N>
class MyClass
{
public:
template <typename... Args>
void foo(Args&&... args)
{
static_assert(sizeof...(Args) == N, "Wrong number of arguments.");
// Rest of the implementation.
}
};
Run Code Online (Sandbox Code Playgroud)
你的第三个变种的第二个非类型参数应该有前缀typename不是class :
template<class...T2, typename std::enable_if<sizeof...(T2) == N, int>::type = 0>
void foo(T2... args);
..
foo(1,2,3);
Run Code Online (Sandbox Code Playgroud)
Gcc 4.7.0快照有一些模板的错误我想,如果你用gcc 4.6.2/1尝试它应该工作.