| 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 | |