我正在尝试创建一个继承多个类(由可变参数模板定义)的类,并且对于每个类,将相同的 args 参数包传递给每个类的构造函数。但是,似乎我无法解压类的可变参数模板和 args 的参数包。
我有一个类:
template<class... __Policies>
class GenericPolicyAdapter : public __Policies...{
使用构造函数:
template<class... __Args>
GenericPolicyAdapter( __Args... args ) : __Policies( args... ){
和测试:
GenericPolicyAdapter<T1,T2> generic_policy_adapter( arg1, arg2, arg3 );
gcc 失败:
error: type ‘__Policies’ is not a direct base of ‘GenericPolicyAdapter<T1,T2>’
其中 __Policies = T1, T2
为了澄清,我本质上是在尝试这样做:
GenericPolicyAdapter : public T1, public T2
{
public:
template<class... __Args>
GenericPolicyAdapter( __Args... args ) : T1( args... ), T2( args... ){}
};
但是使用 T1
和T2
从 __Policies
推导出来
有什么想法吗?看起来 gcc 将 __Policies 视为单一类型而不是类型列表。提前致谢!
编辑:
我应该澄清我正在使用 gcc/g++ 4.4.5。
Howard Hinnant 的建议是:
template<class... __Args>
GenericPolicyAdapter( __Args... args )
: __Policies( args...)...
{}
但是,对于 gcc/g++ 4.4.5,这会导致包扩展表达式的使用无效。很高兴这可以在 OSX/clang 中工作,但是有没有办法在 gcc/g++ 中做到这一点?
I'm trying to create a class that inherits from multiple classes (as defined by a variadic template) and, for each class, passes the same parameter pack of args to the constructor of each class. However, it seems as though I'm not able to unpack both the variadic template of classes and the parameter pack of args.
I have a class:
template<class... __Policies>
class GenericPolicyAdapter : public __Policies...{
With constructor:
template<class... __Args>
GenericPolicyAdapter( __Args... args ) : __Policies( args... ){
and test:
GenericPolicyAdapter<T1,T2> generic_policy_adapter( arg1, arg2, arg3 );
gcc fails with:
error: type ‘__Policies’ is not a direct base of ‘GenericPolicyAdapter<T1,T2>’
where __Policies = T1, T2
To clarify, I'm essentially trying to do:
GenericPolicyAdapter : public T1, public T2
{
public:
template<class... __Args>
GenericPolicyAdapter( __Args... args ) : T1( args... ), T2( args... ){}
};
but with T1
and T2
deduced from __Policies
Any ideas? It seems like gcc is treating __Policies
as a single type rather than a list of types. Thanks in advance!
Edit:
I should clarify that I'm using gcc/g++ 4.4.5.
The suggestion by Howard Hinnant was to do:
template<class... __Args>
GenericPolicyAdapter( __Args... args )
: __Policies( args...)...
{}
However, with gcc/g++ 4.4.5, this gives invalid use of pack expansion expression
. It's great that this works in OSX/clang but is there a way to do this in gcc/g++?
发布评论
评论(3)
“
...
”很像“typename
”。你只需要继续积极地撒布它,直到事情编译完成。 :-)"
...
" is a lot like "typename
". You just have to keep aggressively sprinkling it around until things compile. :-)来自 http://www.open-std.org/jtc1/sc22 /wg21/docs/papers/2011/n3242.pdf
我认为
f(h(args ...) + args ...);
可能是您将得到的最接近的标准示例。请注意,如果您这样做了:
您将提取构造函数参数列表的单个参数,并将它们按顺序应用到基本构造函数。关键是在展开
args
之后再展开__Policies
。From http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf
I think that
f(h(args ...) + args ...);
might be the closest standardese example you will get.Note that if you had done:
You would have pulled a single arg of the constructor parameter list, and applied them in order to the base constructors. The key is to expand
__Policies
after you expandargs
.正如上面评论中提到的,目前 gcc 对可变参数模板的支持相当薄弱。尤其是在参数包扩展方面。 Gcc 4.6 甚至无法将包扩展为固定长度的列表。
以下代码是一种可能的解决方法,它基于一种更复杂的方法来解决我通常使用的这些限制。它只会在 svn 的最新 gcc 上进行编译:
所有发布的 gcc 都会因以下问题而窒息:
这也可能通过更多间接方式解决,但这应该是一个很好的起点(取决于您想要多少可移植性)。
As mentioned above in a comment, gcc is pretty weak on variadic template support to day. Especially when it comes to parameter pack expansions. Gcc 4.6 can not even expand packs into fixed length lists.
The following code is a possible workaround that is based on a far more complex way of working around those limitations that I usually use. It will only compile on a very recent gcc from svn:
All released gccs will choke on this with:
which can possibly also worked around by even more indirection, but this should be a good starting point (depending on how much portability you want).