File: p9.cpp

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (56 lines) | stat: -rw-r--r-- 2,350 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// RUN:  %clang_cc1 -std=c++20 -verify %s
// [temp.deduct.p9]
// A lambda-expression appearing in a function type or a template parameter is
// not considered part of the immediate context for the purposes of template
// argument deduction.
// [Note: The intent is to avoid requiring implementations to deal with
// substitution failure involving arbitrary statements.]
template <class T>
auto f(T) -> decltype([]() { T::invalid; } ());
void f(...);
void test_f() {
  f(0); // expected-error@-3 {{type 'int' cannot be used prior to '::'}}
        // expected-note@-1 {{while substituting deduced template arguments}}
        // expected-note@-5 {{while substituting into a lambda expression here}}
}

template <class T, unsigned = sizeof([]() { T::invalid; })>
void g(T);
void g(...);
void test_g() {
  g(0); // expected-error@-4 {{type 'int' cannot be used prior to '::'}}
        // expected-note@-4 {{in instantiation of default argument}}
        // expected-note@-2 {{while substituting deduced template arguments}}
        // expected-note@-7 {{while substituting into a lambda expression here}}
}

template <class T>
auto h(T) -> decltype([x = T::invalid]() { });
void h(...);
void test_h() {
  h(0); // expected-error@-3 {{type 'int' cannot be used prior to '::'}}
        // expected-note@-1 {{while substituting deduced template arguments}}
        // expected-note@-5 {{while substituting into a lambda expression here}}
}

template <class T>
auto i(T) -> decltype([]() -> typename T::invalid { });
void i(...);
void test_i() {
  i(0); // expected-error@-3 {{type 'int' cannot be used prior to '::'}}
        // expected-note@-1 {{while substituting deduced template arguments}}
        // expected-note@-5 {{while substituting into a lambda expression here}}
}


// In this example, the lambda itself is not part of an immediate context, but
// substitution to the lambda expression succeeds, producing dependent
// `decltype(x.invalid)`. The call to the lambda, however, is in the immediate context
// and it produces a SFINAE failure. Hence, we pick the second overload
// and don't produce any errors.
template <class T>
auto j(T t) -> decltype([](auto x) -> decltype(x.invalid) { } (t));   // #1
void j(...);                                                          // #2
void test_j() {
  j(0); // deduction fails on #1, calls #2.
}