The below code is rejected by GCC 6.1.0(similar bug, https://gcc.gnu.org/bugzilla/show_bug.cgi?id=70845), 6.3.0, 6.4.0, and 7.1.0, but accepted by GCC 5.4.0. I think the code is valid according to the language standard. Building options: g++ test.cpp --std=c++14 (or g++ test.cpp --std=c++11) test.cpp is as below: ///////////////////////////////////////////// #include <utility> struct A : public std::pair< int, int> { using std::pair<int, int>::pair; }; int main() { std::pair<int, int> p{1, 2}; A a(p); } /////////////////////////////////////////// Error Message produced by GCC 6.4.0(Building Option: g++ test.cpp --std=c++14, other rejected versions show similar error message): test.cpp: In function ‘int main()’: test.cpp:9:10: error: no matching function for call to ‘A::A(std::pair<int, int>&)’ A a(p); ^ test.cpp:4:32: note: candidate: template<class _U1, class _U2, typename std::enable_if<(_ConstructiblePair<_U1, _U2>() && _ImplicitlyConvertiblePair<_U1, _U2>()), bool>::type <anonymous> > constexpr A::A(const int&, const int&) using std::pair<int, int>::pair; ^~~~ test.cpp:4:32: note: template argument deduction/substitution failed: test.cpp:9:10: note: candidate expects 2 arguments, 1 provided A a(p); ^ test.cpp:4:32: note: candidate: template<class _U1, class _U2, typename std::enable_if<(_ConstructiblePair<_U1, _U2>() && (! _ImplicitlyConvertiblePair<_U1, _U2>())), bool>::type <anonymous> > constexpr A::A(const int&, const int&) using std::pair<int, int>::pair; ^~~~ test.cpp:4:32: note: template argument deduction/substitution failed: test.cpp:9:10: note: candidate expects 2 arguments, 1 provided A a(p); ^ test.cpp:4:32: note: candidate: template<class _U1, class _U2, typename std::enable_if<(std::_PCC<((! std::is_same<int, _U1>::value) || (! std::is_same<int, _U2>::value)), int, int>::_ConstructiblePair<_U1, _U2>() && std::_PCC<((! std::is_same<int, _U1>::value) || (! std::is_same<int, _U2>::value)), int, int>::_ImplicitlyConvertiblePair<_U1, _U2>()), bool>::type <anonymous> > constexpr A::A(const std::pair<_T1, _T2>&) using std::pair<int, int>::pair; ^~~~ test.cpp:4:32: note: template argument deduction/substitution failed: In file included from /home/tuweiwei/tools/gcc-6.4.0/include/c++/6.4.0/utility:70:0, from test.cpp:1: /home/tuweiwei/tools/gcc-6.4.0/include/c++/6.4.0/bits/stl_pair.h:275:18: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’ bool>::type=true> ^~~~ /home/tuweiwei/tools/gcc-6.4.0/include/c++/6.4.0/bits/stl_pair.h:275:18: note: invalid template non-type parameter test.cpp:4:32: note: candidate: template<class _U1, class _U2, typename std::enable_if<(std::_PCC<((! std::is_same<int, _U1>::value) || (! std::is_same<int, _U2>::value)), int, int>::_ConstructiblePair<_U1, _U2>() && (! std::_PCC<((! std::is_same<int, _U1>::value) || (! std::is_same<int, _U2>::value)), int, int>::_ImplicitlyConvertiblePair<_U1, _U2>())), bool>::type <anonymous> > constexpr A::A(const std::pair<_T1, _T2>&) using std::pair<int, int>::pair; ^~~~ test.cpp:4:32: note: template argument deduction/substitution failed: In file included from /home/tuweiwei/tools/gcc-6.4.0/include/c++/6.4.0/utility:70:0, from test.cpp:1: /home/tuweiwei/tools/gcc-6.4.0/include/c++/6.4.0/bits/stl_pair.h:284:38: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’ bool>::type=false> ^~~~~ /home/tuweiwei/tools/gcc-6.4.0/include/c++/6.4.0/bits/stl_pair.h:284:38: note: invalid template non-type parameter test.cpp:4:32: note: candidate: template<class _U1, typename std::enable_if<_MoveCopyPair<true, _U1, int>(), bool>::type <anonymous> > constexpr A::A(_U1&&, const int&) using std::pair<int, int>::pair; ^~~~ test.cpp:4:32: note: template argument deduction/substitution failed: test.cpp:9:10: note: candidate expects 2 arguments, 1 provided A a(p); ^ test.cpp:4:32: note: candidate: template<class _U1, typename std::enable_if<_MoveCopyPair<false, _U1, int>(), bool>::type <anonymous> > constexpr A::A(_U1&&, const int&) using std::pair<int, int>::pair; ^~~~ test.cpp:4:32: note: template argument deduction/substitution failed: test.cpp:9:10: note: candidate expects 2 arguments, 1 provided A a(p); ^ test.cpp:4:32: note: candidate: template<class _U2, typename std::enable_if<_CopyMovePair<true, int, _U2>(), bool>::type <anonymous> > constexpr A::A(const int&, _U2&&) using std::pair<int, int>::pair; ^~~~ test.cpp:4:32: note: template argument deduction/substitution failed: test.cpp:9:10: note: candidate expects 2 arguments, 1 provided A a(p); ^ test.cpp:4:32: note: candidate: template<class _U2, typename std::enable_if<_CopyMovePair<false, int, _U2>(), bool>::type <anonymous> > A::A(const int&, _U2&&) using std::pair<int, int>::pair; ^~~~ test.cpp:4:32: note: template argument deduction/substitution failed: test.cpp:9:10: note: candidate expects 2 arguments, 1 provided A a(p); ^ test.cpp:4:32: note: candidate: template<class _U1, class _U2, typename std::enable_if<(_MoveConstructiblePair<_U1, _U2>() && _ImplicitlyMoveConvertiblePair<_U1, _U2>()), bool>::type <anonymous> > constexpr A::A(_U1&&, _U2&&) using std::pair<int, int>::pair; ^~~~ test.cpp:4:32: note: template argument deduction/substitution failed: test.cpp:9:10: note: candidate expects 2 arguments, 1 provided A a(p); ^ test.cpp:4:32: note: candidate: template<class _U1, class _U2, typename std::enable_if<(_MoveConstructiblePair<_U1, _U2>() && (! _ImplicitlyMoveConvertiblePair<_U1, _U2>())), bool>::type <anonymous> > constexpr A::A(_U1&&, _U2&&) using std::pair<int, int>::pair; ^~~~ test.cpp:4:32: note: template argument deduction/substitution failed: test.cpp:9:10: note: candidate expects 2 arguments, 1 provided A a(p); ^ test.cpp:4:32: note: candidate: template<class _U1, class _U2, typename std::enable_if<(std::_PCC<((! std::is_same<int, _U1>::value) || (! std::is_same<int, _U2>::value)), int, int>::_MoveConstructiblePair<_U1, _U2>() && std::_PCC<((! std::is_same<int, _U1>::value) || (! std::is_same<int, _U2>::value)), int, int>::_ImplicitlyMoveConvertiblePair<_U1, _U2>()), bool>::type <anonymous> > constexpr A::A(std::pair<_T1, _T2>&&) using std::pair<int, int>::pair; ^~~~ test.cpp:4:32: note: template argument deduction/substitution failed: In file included from /home/tuweiwei/tools/gcc-6.4.0/include/c++/6.4.0/utility:70:0, from test.cpp:1: /home/tuweiwei/tools/gcc-6.4.0/include/c++/6.4.0/bits/stl_pair.h:344:38: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’ bool>::type=true> ^~~~ /home/tuweiwei/tools/gcc-6.4.0/include/c++/6.4.0/bits/stl_pair.h:344:38: note: invalid template non-type parameter test.cpp:4:32: note: candidate: template<class _U1, class _U2, typename std::enable_if<(std::_PCC<((! std::is_same<int, _U1>::value) || (! std::is_same<int, _U2>::value)), int, int>::_MoveConstructiblePair<_U1, _U2>() && (! std::_PCC<((! std::is_same<int, _U1>::value) || (! std::is_same<int, _U2>::value)), int, int>::_ImplicitlyMoveConvertiblePair<_U1, _U2>())), bool>::type <anonymous> > constexpr A::A(std::pair<_T1, _T2>&&) using std::pair<int, int>::pair; ^~~~ test.cpp:4:32: note: template argument deduction/substitution failed: In file included from /home/tuweiwei/tools/gcc-6.4.0/include/c++/6.4.0/utility:70:0, from test.cpp:1: /home/tuweiwei/tools/gcc-6.4.0/include/c++/6.4.0/bits/stl_pair.h:354:38: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’ bool>::type=false> ^~~~~ /home/tuweiwei/tools/gcc-6.4.0/include/c++/6.4.0/bits/stl_pair.h:354:38: note: invalid template non-type parameter test.cpp:4:32: note: candidate: template<class ... _Args1, class ... _Args2> A::A(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) using std::pair<int, int>::pair; ^~~~ test.cpp:4:32: note: template argument deduction/substitution failed: test.cpp:9:10: note: candidate expects 3 arguments, 1 provided A a(p); ^ test.cpp:4:32: note: candidate: template<class ... _Args1, long unsigned int ..._Indexes1, class ... _Args2, long unsigned int ..._Indexes2> A::A(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Ind2 ...>, std::_Index_tuple<_Indexes2 ...>) using std::pair<int, int>::pair; ^~~~ test.cpp:4:32: note: template argument deduction/substitution failed: test.cpp:9:10: note: ‘std::pair<int, int>’ is not derived from ‘std::tuple<_Args1 ...>’ A a(p); ^ test.cpp:3:8: note: candidate: constexpr A::A() struct A : public std::pair< int, int> { ^ test.cpp:3:8: note: candidate expects 0 arguments, 1 provided test.cpp:3:8: note: candidate: constexpr A::A(const A&) test.cpp:3:8: note: no known conversion for argument 1 from ‘std::pair<int, int>’ to ‘const A&’ test.cpp:3:8: note: candidate: constexpr A::A(A&&) test.cpp:3:8: note: no known conversion for argument 1 from ‘std::pair<int, int>’ to ‘A&&’
Some additional information: The above code is REJECTED by GCC 6.2.0 too. But the below code is PASSED by GCC 6.1.0, 6.3.0, 6.4.0, 7.1.0. The only difference is explicitly casting p's type to its own type. ///////////////////////////////////////////// #include <utility> struct A : public std::pair< int, int> { using std::pair<int, int>::pair; }; int main() { std::pair<int, int> p{1, 2}; A a(std::pair<int, int>(p)); } ///////////////////////////////////////////
> The above code is REJECTED by GCC 6.2.0 too. ==> Sorry for the mistake, The above code is ACCEPTED by GCC 6.2.0 too. (In reply to Wei-Wei Tu from comment #1) > Some additional information: > > The above code is REJECTED by GCC 6.2.0 too. > > But the below code is PASSED by GCC 6.1.0, 6.3.0, 6.4.0, 7.1.0. The only > difference is explicitly casting p's type to its own type. > > ///////////////////////////////////////////// > #include <utility> > > struct A : public std::pair< int, int> { > using std::pair<int, int>::pair; > }; > > int main() { > std::pair<int, int> p{1, 2}; > A a(std::pair<int, int>(p)); > } > ///////////////////////////////////////////
I don't think the code is valid, copy/move constructors are not inherited. See PR 69853 for a similar bug report. *** This bug has been marked as a duplicate of bug 69853 ***
(In reply to Jonathan Wakely from comment #3) > I don't think the code is valid, copy/move constructors are not inherited. > See PR 69853 for a similar bug report. > > *** This bug has been marked as a duplicate of bug 69853 *** Yes, you are right. I've made a mistake about "using". Thank you for checking this report.