【问题标题】:zero length variadic expansion of ill-formed call病态调用的零长度可变参数展开
【发布时间】:2017-09-28 17:16:43
【问题描述】:

标准大师的问题。

试图回复another question,我开始怀疑代码的格式是否正确。

据我所知,以下代码格式不正确

int main ()
 {
   std::tuple<>  a;

   std::get<0>(a);
 }

因为当tstd::tuple&lt;Ts...&gt; 时,对std::get&lt;I&gt;(t) 的调用在I 超出[0, sizeof...(Ts)[ 的范围时是不正确的。

在这种情况下,sizeof...(Ts) 为零,因此范围 [0, 0[ 为空,因此对于每个索引 Istd::get&lt;I&gt;(a) 的格式都是错误的。

但是当std::get&lt;I&gt;(a) 被一个空的可变参数包扩展时呢?

我的意思是:下面的代码

#include <tuple>

template <typename ... Args>
void bar (Args const & ...)
 { }

template <std::size_t ... I>
void foo ()
 {
   std::tuple<> a;

   bar( std::get<I>(a) ... );
 }

int main ()
 {
   foo<>();
 }

使用格式不正确的 (?) 调用 (std::get&lt;I&gt;(a)) 但零时间可变参数展开(sizeof...(I) 为零),是格式正确还是格式错误?

【问题讨论】:

    标签: c++ c++11 templates variadic-templates well-formed


    【解决方案1】:

    [temp.res]/8:

    程序格式错误,不需要诊断,如果:

    • [...]
    • 可变参数模板的每个有效特化都需要一个空模板参数包,或者
    • [...]

    【讨论】:

    • 请注意,由于 OP 试图简化问题,它的格式不正确 :-/ (因为原版更接近 get&lt;Is&gt;(tuple_of_size&lt;Is&gt;{})...)。
    • 顺便说一句,这意味着在实现应用时很难避免这个陷阱。
    • @Jarod42 - 抱歉:“原样”是指我链接的问题吗?
    • @max66:确实是的。
    • @Jarod42 - 我明白了。但是,如果我没记错的话,在那个问题中(参见“编译器资源管理器”中链接的代码)varstd::tuple&lt;&gt;(当是 std::tuple&lt;int&gt; 时警告消失)。
    猜你喜欢
    • 1970-01-01
    • 2017-02-06
    • 1970-01-01
    • 2021-08-31
    • 1970-01-01
    • 2011-06-02
    • 2012-12-25
    • 2011-07-08
    • 1970-01-01
    相关资源
    最近更新 更多