Bug 81527 - Missing inherited constructor by "using-declarations"
Summary: Missing inherited constructor by "using-declarations"
Status: RESOLVED DUPLICATE of bug 69853
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 6.4.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-07-24 05:12 UTC by Wei-Wei Tu
Modified: 2017-07-26 00:58 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Wei-Wei Tu 2017-07-24 05:12:35 UTC
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&&’
Comment 1 Wei-Wei Tu 2017-07-24 10:58:28 UTC
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));
}
///////////////////////////////////////////
Comment 2 Wei-Wei Tu 2017-07-24 10:59:53 UTC
> 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));
> }
> ///////////////////////////////////////////
Comment 3 Jonathan Wakely 2017-07-25 21:07:50 UTC
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 ***
Comment 4 Wei-Wei Tu 2017-07-26 00:58:45 UTC
(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.