https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81527
Bug ID: 81527 Summary: Missing inherited constructor by "using-declarations" Product: gcc Version: 6.4.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: tuwwcn at gmail dot com Target Milestone: --- 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&&’