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

Better pack expansion syntax in variadic template?

谈论已经一成不变的语言语法可能效率不高。

但是,我想看看为什么 C++11 variadic template's argument expansion 在涉及某些嵌套用法时不能 更明确地阅读

例如,我认为 C++ 开发人员通常可以将代码编写得更清楚,如下所示。 (如果允许的话)

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;

通过这样做,我们真的不必混淆哪些模板类型正在被扩展,或者应该是在制作多重嵌套时必须扩展的模板类型 variadic template,因为那样它就变成了让您的代码看起来更清晰比缩短更重要。

此外,我希望以与调用函数相同的方式查看代码,如下所示:

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

我们不这样做:

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

编辑

我相信这个至少应该被允许很好地工作。

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

但事实并非如此。

为什么不呢? 说服委员会阻止其编译是否存在任何潜在风险?

在此先感谢您。

在您的每一种情况下,您的 "preferred" 符号都会执行与您想要的不同 扩展。它们不是无效的。

如果 Args0 = { a,b,c } 且 Args1 = { int,double,char } 那么:

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

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

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

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

事实是,这些都是有用的操作。

关键是 ... 对潜在扩展的子 "expressions" 进行操作,而不是直接对包进行操作。

除非您提出的符号可以产生这两个结果,否则它是一个较弱的符号。

Foo(Args)...Foo(Args...) 也是如此。它们不是表达某事的替代方式——它们是在当前 C++ 中表达两种不同事物的方式。您的计划导致第 2 表示第 1,这意味着在您的 C++ 版本中不再有表达第 2 表示的方法。

每个扩展包有两个部分。第一个是什么包正在扩展,第二个是什么"expression"正在扩展。在当前的 C++ 中,被扩展的包都是表达式中未扩展的包:它们没有另外标记。

在您的版本中,您将包标记为要扩展,而从不将表达式标记为要扩展。如果语言能读懂你的想法,它可以找出表达式的位置,但读懂你想法的编程语言通常不是一个好主意。

"mark the expression, not the pack" 的一个副作用是您可以做一些非常强大的事情,比如在主体内的表达式中包含包含未扩展包的整个 lambda,然后生成一组 lambda。在您的系统中表达这一点将具有挑战性。