1 | // RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s |
2 | // RUN: %clang_cc1 -std=c++1z -fsyntax-only -verify %s |
3 | |
4 | // A forwarding reference is an rvalue reference to a cv-unqualified template |
5 | // parameter that does not represent a template parameter of a class template. |
6 | #if __cplusplus > 201402L |
7 | namespace ClassTemplateParamNotForwardingRef { |
8 | // This is not a forwarding reference. |
9 | template<typename T> struct A { // expected-note {{candidate}} |
10 | A(T&&); // expected-note {{no known conversion from 'int' to 'int &&'}} |
11 | }; |
12 | int n; |
13 | A a = n; // expected-error {{no viable constructor or deduction guide}} |
14 | |
15 | A b = 0; |
16 | A<int> *pb = &b; |
17 | |
18 | // This is a forwarding reference. |
19 | template<typename T> A(T&&) -> A<T>; |
20 | A c = n; |
21 | A<int&> *pc = &c; |
22 | |
23 | A d = 0; |
24 | A<int> *pd = &d; |
25 | |
26 | template<typename T = void> struct B { |
27 | // This is a forwarding reference. |
28 | template<typename U> B(U &&); |
29 | }; |
30 | B e = n; |
31 | B<void> *pe = &e; |
32 | } |
33 | #endif |
34 | |
35 | // If P is a forwarding reference and the argument is an lvalue, the type |
36 | // "lvalue reference to A" is used in place of A for type deduction. |
37 | template<typename T> struct X { }; |
38 | |
39 | template<typename T> X<T> f0(T&&); |
40 | |
41 | struct Y { }; |
42 | |
43 | template<typename T> T prvalue(); |
44 | template<typename T> T&& xvalue(); |
45 | template<typename T> T& lvalue(); |
46 | |
47 | void test_f0() { |
48 | X<int> xi0 = f0(prvalue<int>()); |
49 | X<int> xi1 = f0(xvalue<int>()); |
50 | X<int&> xi2 = f0(lvalue<int>()); |
51 | X<Y> xy0 = f0(prvalue<Y>()); |
52 | X<Y> xy1 = f0(xvalue<Y>()); |
53 | X<Y&> xy2 = f0(lvalue<Y>()); |
54 | } |
55 | |
56 | template<typename T> X<T> f1(const T&&); // expected-note{{candidate function [with T = int] not viable: no known conversion from 'int' to 'const int &&' for 1st argument}} \ |
57 | // expected-note{{candidate function [with T = Y] not viable: no known conversion from 'Y' to 'const Y &&' for 1st argument}} |
58 | |
59 | void test_f1() { |
60 | X<int> xi0 = f1(prvalue<int>()); |
61 | X<int> xi1 = f1(xvalue<int>()); |
62 | f1(lvalue<int>()); // expected-error{{no matching function for call to 'f1'}} |
63 | X<Y> xy0 = f1(prvalue<Y>()); |
64 | X<Y> xy1 = f1(xvalue<Y>()); |
65 | f1(lvalue<Y>()); // expected-error{{no matching function for call to 'f1'}} |
66 | } |
67 | |
68 | namespace std_example { |
69 | template <class T> int f(T&&); |
70 | template <class T> int g(const T&&); // expected-note{{candidate function [with T = int] not viable: no known conversion from 'int' to 'const int &&' for 1st argument}} |
71 | |
72 | int i; |
73 | int n1 = f(i); |
74 | int n2 = f(0); |
75 | int n3 = g(i); // expected-error{{no matching function for call to 'g'}} |
76 | |
77 | #if __cplusplus > 201402L |
78 | template<class T> struct A { // expected-note {{candidate}} |
79 | template<class U> |
80 | A(T &&, U &&, int *); // expected-note {{[with T = int, U = int] not viable: no known conversion from 'int' to 'int &&'}} |
81 | A(T &&, int *); // expected-note {{requires 2}} |
82 | }; |
83 | template<class T> A(T &&, int *) -> A<T>; // expected-note {{requires 2}} |
84 | |
85 | int *ip; |
86 | A a{i, 0, ip}; // expected-error {{no viable constructor or deduction guide}} |
87 | A a0{0, 0, ip}; |
88 | A a2{i, ip}; |
89 | |
90 | A<int> &a0r = a0; |
91 | A<int&> &a2r = a2; |
92 | #endif |
93 | } |
94 | |