26

次の「ts」の暗黙のキャプチャが整形式であるかどうかを誰かが知っていますか?

template<class ... Ts> void bar(Ts ... ts) { }

template<class ... Ts> int foo(Ts ... ts) {
    auto L = [=] () {
       bar(ts...);
    };
    L();
    return 0;
}
int g = foo(1, 2, 3);

規格は、これがうまく形成されるべきではないとどこかに明確に述べていますか?

4

2 に答える 2

13

14.5.3 / 6:

式ではないパック拡張をインスタンス化するとsizeof...、リストE1、E2、...、ENが生成されます。ここで、Nはパック拡張パラメーター内の要素の数です。各Eiは、パターンをインスタンス化し、各パック拡張パラメーターをそのi番目の要素に置き換えることによって生成されます。すべてのEiは、囲んでいるリストの要素になります。

パックを明示的にキャプチャすることが許可されているかどうかに関係なく(を使用して[ts ...])、拡張の一般的なルールにより、リストの各要素がキャプチャされます。

于 2013-01-11T03:17:47.997 に答える
7

私はそれが整形式であると思います、私はまっすぐな声明を見つけませんでした(言葉遣いは時々特定の状況のた​​めの明確さ/イラストに欠けます)、しかし私はそれが推測されるかもしれないと思います:

§5.1.2/23:

キャプチャとそれに続く省略記号は、パック拡張(14.5.3)です。[ 例:

      template<class... Args>
      void f(Args... args) {
        auto lm = [&, args...] { return g(args...); };
        lm();
      }

—終了例]

  • キャプチャの後に省略記号が続くargs場合は、ラムダキャプチャでのキャプチャの例(この場合は明示的)であり、注目すべき事実はargsパラメータパック識別子です。この短い段落は、ラムダキャプチャがパック拡張を保持する方法を説明する唯一の役割を果たします。これは、パラメータパックをキャプチャできるようにすることを目的としていない場合でも、パラメータパックをキャプチャできることを示しています。

§5.1.2/12:

エンティティが明示的または暗黙的にキャプチャされた場合、エンティティはキャプチャされます。[...]

§3/3:

エンティティは、値、オブジェクト、参照、関数、列挙子、型、クラスメンバー、テンプレート、テンプレートの特殊化、名前空間、パラメーターパック、またはこれです。

このことから、パラメータパックは明示的または暗黙的にキャプチャできるエンティティであると想定します。したがって、パラメータパックがそれに応じて拡張されることを除いて、通常の変数と同じキャプチャルールが適用されます。

あなたの質問(および同じ議論)は、たとえば参照変数にも同様に適用できると思います(参照にストレージが必要かどうかは指定されていません。§8.3.2/ 4)。ラムダ内のパラメーターパック識別子を参照することが許可されているかどうかに関心があるようです。

外部スコープの参照変数についても同じように考えることができます。これは、それらにアクセスできる可能性があるが、元の変数の識別子にアクセスすることさえ許可されていないためです。

それらはパラメータパックと同じくらいエーテル的です。

于 2013-01-11T03:53:12.507 に答える