Home | History | Annotate | Download | only in expr.prim.lambda
      1 // RUN: %clang_cc1 -std=c++1y %s -verify
      2 
      3 const char *has_no_member = [x("hello")] {}.x; // expected-error {{no member named 'x'}}
      4 
      5 double f;
      6 auto with_float = [f(1.0f)] {
      7   using T = decltype(f);
      8   using T = float;
      9 };
     10 auto with_float_2 = [&f(f)] { // ok, refers to outer f
     11   using T = decltype(f);
     12   using T = double&;
     13 };
     14 
     15 // Within the lambda-expression's compound-statement,
     16 // the identifier in the init-capture hides any declaration
     17 // of the same name in scopes enclosing the lambda-expression.
     18 void hiding() {
     19   char c;
     20   (void) [c("foo")] {
     21     static_assert(sizeof(c) == sizeof(const char*), "");
     22   };
     23   (void) [c("bar")] () -> decltype(c) { // outer c, not init-capture
     24     return "baz"; // expected-error {{cannot initialize}}
     25   };
     26 }
     27 
     28 struct ExplicitCopy {
     29   ExplicitCopy(); // expected-note 2{{not viable}}
     30   explicit ExplicitCopy(const ExplicitCopy&);
     31 };
     32 auto init_kind_1 = [ec(ExplicitCopy())] {};
     33 auto init_kind_2 = [ec = ExplicitCopy()] {}; // expected-error {{no matching constructor}}
     34 
     35 template<typename T> void init_kind_template() {
     36   auto init_kind_1 = [ec(T())] {};
     37   auto init_kind_2 = [ec = T()] {}; // expected-error {{no matching constructor}}
     38 }
     39 template void init_kind_template<int>();
     40 template void init_kind_template<ExplicitCopy>(); // expected-note {{instantiation of}}
     41 
     42 void void_fn();
     43 int overload_fn();
     44 int overload_fn(int);
     45 
     46 auto bad_init_1 = [a()] {}; // expected-error {{expected expression}}
     47 auto bad_init_2 = [a(1, 2)] {}; // expected-error {{initializer for lambda capture 'a' contains multiple expressions}}
     48 auto bad_init_3 = [&a(void_fn())] {}; // expected-error {{cannot form a reference to 'void'}}
     49 auto bad_init_4 = [a(void_fn())] {}; // expected-error {{has incomplete type 'void'}}
     50 auto bad_init_5 = [a(overload_fn)] {}; // expected-error {{cannot deduce type for lambda capture 'a' from initializer of type '<overloaded function}}
     51 auto bad_init_6 = [a{overload_fn}] {}; // expected-error {{cannot deduce type for lambda capture 'a' from initializer list}}
     52 
     53 template<typename...T> void pack_1(T...t) { (void)[a(t...)] {}; } // expected-error {{initializer missing for lambda capture 'a'}}
     54 template void pack_1<>(); // expected-note {{instantiation of}}
     55 
     56 // FIXME: Might need lifetime extension for the temporary here.
     57 // See DR1695.
     58 auto a = [a(4), b = 5, &c = static_cast<const int&&>(0)] {
     59   static_assert(sizeof(a) == sizeof(int), "");
     60   static_assert(sizeof(b) == sizeof(int), "");
     61   using T = decltype(c);
     62   using T = const int &;
     63 };
     64 auto b = [a{0}] {}; // expected-error {{include <initializer_list>}}
     65 
     66 struct S { S(); S(S&&); };
     67 template<typename T> struct remove_reference { typedef T type; };
     68 template<typename T> struct remove_reference<T&> { typedef T type; };
     69 template<typename T> decltype(auto) move(T &&t) { return static_cast<typename remove_reference<T>::type&&>(t); }
     70 auto s = [s(move(S()))] {};
     71 
     72 template<typename T> T instantiate_test(T t) {
     73   [x(&t)]() { *x = 1; } (); // expected-error {{assigning to 'const char *'}}
     74   return t;
     75 }
     76 int instantiate_test_1 = instantiate_test(0);
     77 const char *instantiate_test_2 = instantiate_test("foo"); // expected-note {{here}}
     78