简体   繁体   English

可变参数模板中更好的包扩展语法?

[英]Better pack expansion syntax in variadic template?

It might be not very efficient to talk about the language syntax that has already been set in stone. 谈论已经刻板的语言语法可能不是很有效。

I would, however, like to see why the C++11 variadic template's argument expansion couldn't be more explicit to read when it comes to some nested usage. 但是,我想看看为什么C++11 variadic template's argument expansion在涉及嵌套用法时不能更明确地读取

For example, I think C++ developers could've generally written code more clearly as follows. 例如,我认为C ++开发人员通常可以更清晰地编写如下代码。 (If that's allowed) (如果允许)

template<typename ...> struct Tuple 
{

};

template<typename T1, typename T2> struct Pair 
{

};

template<class ...Args1> struct zip 
{
    template<class ...Args2> struct with 
    {   
        typedef Tuple<Pair<Args1, Args2>...> type;

        // More code but but maybe better readability?
        // because Args1, and Args2 are the ones that get 
        // actually expanded, not Pair<T1, T2>.
        // typedef Tuple<Pair<Args1..., Args2...>> type; // ## Invalid! ##
    };
};


typedef zip<short, int>::with<unsigned short, unsigned>::type T1;

By doing so we don't really have to get confused which template types are exactly being expanded or should be the ones that will have to be expanded when making multiple-nested variadic template , because then it becomes more important for your code to look clearer than being shortened. 这样一来,在制作多重嵌套variadic template ,我们就不必真正混淆要扩展的模板类型或应该扩展的模板类型,因为这样对于您的代码来说,变得更加清晰就显得尤为重要比被缩短。

Plus I'd love to see the code in the same manner where I call a function as follows: 另外,我很想以相同的方式查看代码,如下所示:

Foo(args...); // Okay.

We don't do like this: 我们不喜欢这样:

Foo(args)...; // Error.

EDIT 编辑

I believe this one should've been at least allowed to work nicely. 我认为应该至少允许它工作良好。

Tuple<Pair<Args1..., Args2...>> // Invalid code.

But it does not. 但事实并非如此。

Why not? 为什么不? Is there any potential risk to convince the committee enough to prevent it from compiling? 是否有潜在的风险足以说服委员会阻止其编译?

Thank you so much in advance. 提前非常感谢您。

In every one of your cases, your "preferred" notation does a different expansion than the one you want. 在每种情况下,您的“首选”表示法都会与您想要的进行不同的扩展。 They aren't invalid. 它们不是无效的。

If Args0 = { a,b,c } and Args1 = { int,double,char } then: 如果Args0 = { a,b,c }和Args1 = { int,double,char },则:

std::tuple< foo< Args0..., Args1... > >

is

std::tuple< foo< a,b,c,int,double,char > >

while

std::tuple< foo< Args0, Args1>... >

is

std::tuple< foo< a, int >, foo< b, double >, foo< c, char > >

The thing is, these are both useful operations. 事实是,这些都是有用的操作。

The key is ... operates on potentially-expanded sub-"expressions", not on packs directly. 关键是...对可能扩展的子“表达式”进行操作,而不是直接对包装进行操作。

Unless your proposed notation can generate both of these results, it is a weaker notation. 除非您提议的符号可以同时产生这两种结果,否则它是一个较弱的符号。

The same thing holds true with Foo(Args)... and Foo(Args...) . Foo(Args)...Foo(Args...) They aren't alternate ways to say something -- they are ways of saying two different things in current C++. 它们不是说某些东西的替代方法,而是在当前C ++中说两种不同的事情的方法。 Your plan results in in the 2nd meaning the 1st, which means there is no longer a way to express what the 2nd means in your version of C++. 您的计划产生的第二个含义是第一个,这意味着在您的C ++版本中不再有表达第二个含义的方法。

There are two parts to each expansion. 每个扩展有两个部分。 The first is what packs are being expanded, the second is what "expression" is being expanded. 第一个是正在扩展的 ,第二个是正在扩展的“表达式” The packs being expanded, in current C++, are all unexpanded packs within the expression: they are not otherwise marked. 在当前的C ++中,正在扩展的包都是表达式中所有未扩展的包:没有其他标记。

In your version, you mark the packs to expand, and never mark the expression to be expanded. 在您的版本中,您标记了要扩展的包,而从不标记要扩展的表达式。 If the language read your mind, it could figure out where that expression was, but programming languages that read your mind are usually a bad idea. 如果该语言能读懂您的想法,那么它可以弄清楚该表达在哪里,但是能读懂您的思想的编程语言通常是个坏主意。

A side effect of "mark the expression, not the pack" is that you can do some seriously powerful stuff, like have entire lambdas that contain unexpanded packs inside expressions inside the body, and then generate a pack of lambdas. “标记表达式而不是包”的副作用是,您可以执行一些功能强大的操作,例如使整个lambda包含在体内表达式内部的未扩展包,然后生成一包lambda。 Expressing that in your system would be challenging. 在您的系统中表达这一点非常具有挑战性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM