@@ -1369,6 +1369,78 @@ namespace cwg385 { // cwg385: 2.8
13691369 // expected-note@#cwg385-n {{member is declared here}}
13701370}
13711371
1372+ namespace cwg386 { // cwg386: no
1373+ namespace example1 {
1374+ namespace N1 {
1375+ // Binds name 'f' in N1. Target scope is N1.
1376+ template <typename T> void f ( T* x ) {
1377+ // ... other stuff ...
1378+ delete x;
1379+ }
1380+ }
1381+
1382+ namespace N2 {
1383+ // Bind name 'f' in N2. When a single search find this declaration,
1384+ // it's replaced with N1::f declaration.
1385+ using N1::f;
1386+
1387+ // According to _N4988_.[dcl.meaning]/3.3:
1388+ // `f<int>` is not a qualified-id, so its target scope is N2.
1389+ // `f<int>` is a template-id, so 'f' undergoes (unqualified) lookup.
1390+ // Search performed by unqualified lookup finds N1::f via using-declaration,
1391+ // but this result is not considered, because it's not nominable in N2,
1392+ // which is because its target scope is N1.
1393+ // So unqualified lookup doesn't find anything, making this declaration ill-formed.
1394+ template <> void f<int >( int * );
1395+ // expected-error@-1 {{no function template matches function template specialization 'f'}}
1396+
1397+ class Test {
1398+ ~Test () { }
1399+ // According to _N4988_.[dcl.meaning]/2.2:
1400+ // `f<>` is a template-id and not a template declaration,
1401+ // so its terminal name 'f' undergoes (unqualified) lookup.
1402+ // Search in N2 performed by unqualified lookup finds
1403+ // (single) N1::f declaration via using-declaration.
1404+ // N1::f is replaced with N1::f<> specialization after deduction,
1405+ // and this is the result of the unqualified lookup.
1406+ // This friend declaration correspond to the result of the lookup.
1407+ // All lookup results target the same scope, which is N1,
1408+ // so target scope of this friend declaration is also N1.
1409+ // FIXME: This is well-formed.
1410+ friend void f<>( Test* x );
1411+ // expected-error@-1 {{no function template matches function template specialization 'f'}}
1412+ };
1413+ }
1414+ } // namespace example1
1415+
1416+ namespace example2 {
1417+ namespace N1 {
1418+ // Binds name 'f' in N1. Target scope is N1.
1419+ void f (); // #cwg386-ex2-N1-f
1420+ }
1421+
1422+ namespace N2 {
1423+ // Bind name 'f' in N2. When a single search finds this declaration,
1424+ // it's replaced with N1::f declaration.
1425+ using N1::f; // #cwg386-ex2-using
1426+ class A {
1427+ // According to _N4988_.[dcl.meaning]/2.2:
1428+ // `N2::f` is a qualified-id, so its terminal name 'f' undergoes (qualified) lookup.
1429+ // Search in N2 performed by qualified lookup finds N1::f via using-declaration,
1430+ // which is the (only) result of qualified lookup.
1431+ // This friend declaration corresponds to the result of the lookup.
1432+ // All lookup results target the same scope, which is N1,
1433+ // so target scope of this friend declaration is also N1.
1434+ // FIXME: This is well-formed.
1435+ friend void N2::f ();
1436+ // expected-error@-1 {{cannot befriend target of using declaration}}
1437+ // expected-note@#cwg386-ex2-N1-f {{target of using declaration}}
1438+ // expected-note@#cwg386-ex2-using {{using declaration}}
1439+ };
1440+ }
1441+ } // namespace example2
1442+ } // namespace cwg386
1443+
13721444namespace cwg387 { // cwg387: 2.8
13731445 namespace old {
13741446 template <typename T> class number {
0 commit comments