https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69853
Bug ID: 69853 Summary: An inheriting constructor of the class that inherited std::tuple isn't called correctly Product: gcc Version: 6.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ Assignee: unassigned at gcc dot gnu.org Reporter: redboltz at gmail dot com Target Milestone: --- Code #include <tuple> template <typename... Types> struct my_tuple : std::tuple<Types...> { // inheriting constructor using std::tuple<Types...>::tuple; }; int main() { std::tuple<int> st; my_tuple<int> mt(st); } Compiler version $ /home/kondo/local/usr/local/bin/g++ -v Using built-in specs. COLLECT_GCC=/home/kondo/local/usr/local/bin/g++ COLLECT_LTO_WRAPPER=/home/kondo/local/usr/local/bin/../libexec/gcc/x86_64-pc-linux-gnu/6.0.0/lto-wrapper Target: x86_64-pc-linux-gnu Configured with: ../gcc/configure --disable-multilib --enable-languages=c,c++ Thread model: posix gcc version 6.0.0 20160217 (experimental) (GCC) Git (git://gcc.gnu.org/git/gcc.git) hash commit 0d85ea34a029adf4c3c31edaf8a317905d852faa Environment $ uname -a Linux archboltz 4.3.3-2-ARCH #1 SMP PREEMPT Wed Dec 23 20:09:18 CET 2015 x86_64 GNU/Linux Error log $ /home/kondo/local/usr/local/bin/g++ -std=c++11 test.cpp test.cpp: In function ‘int main()’: test.cpp:11:24: error: no matching function for call to ‘my_tuple<int>::my_tuple(std::tuple<int>&)’ my_tuple<int> mt(st); ^ test.cpp:4:8: note: candidate: constexpr my_tuple<int>::my_tuple() struct my_tuple : std::tuple<Types...> { ^~~~~~~~ test.cpp:4:8: note: candidate expects 0 arguments, 1 provided test.cpp:6:33: note: candidate: template<class _Dummy, typename std::enable_if<((std::_TC<std::is_same<_Dummy, void>::value, int>::_ConstructibleTuple<int>() && std::_TC<std::is_same<_Dummy, void>::value, int>::_ImplicitlyConvertibleTuple<int>()) && (1ul >= 1)), bool>::type <anonymous> > constexpr my_tuple<int>::my_tuple(const int&) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: test.cpp:11:24: note: cannot convert ‘st’ (type ‘std::tuple<int>’) to type ‘const int&’ my_tuple<int> mt(st); ^ test.cpp:6:33: note: candidate: template<class _Dummy, typename std::enable_if<((std::_TC<std::is_same<_Dummy, void>::value, int>::_ConstructibleTuple<int>() && (! std::_TC<std::is_same<_Dummy, void>::value, int>::_ImplicitlyConvertibleTuple<int>())) && (1ul >= 1)), bool>::type <anonymous> > constexpr my_tuple<int>::my_tuple(const int&) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: test.cpp:11:24: note: cannot convert ‘st’ (type ‘std::tuple<int>’) to type ‘const int&’ my_tuple<int> mt(st); ^ test.cpp:6:33: note: candidate: template<class ... _UElements, typename std::enable_if<((std::_TC<(1ul == sizeof... (_UElements)), int>::_MoveConstructibleTuple<_UElements ...>() && std::_TC<(1ul == sizeof... (_UElements)), int>::_ImplicitlyMoveConvertibleTuple<_UElements ...>()) && (1ul >= 1)), bool>::type <anonymous> > constexpr my_tuple<int>::my_tuple(_UElements&& ...) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: In file included from test.cpp:1:0: /home/kondo/local/usr/local/include/c++/6.0.0/tuple:619:21: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’ bool>::type=true> ^~~~ /home/kondo/local/usr/local/include/c++/6.0.0/tuple:619:21: note: invalid template non-type parameter test.cpp:6:33: note: candidate: template<class ... _UElements, typename std::enable_if<((std::_TC<(1ul == sizeof... (_UElements)), int>::_MoveConstructibleTuple<_UElements ...>() && (! std::_TC<(1ul == sizeof... (_UElements)), int>::_ImplicitlyMoveConvertibleTuple<_UElements ...>())) && (1ul >= 1)), bool>::type <anonymous> > constexpr my_tuple<int>::my_tuple(_UElements&& ...) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: In file included from test.cpp:1:0: /home/kondo/local/usr/local/include/c++/6.0.0/tuple:629:21: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’ bool>::type=false> ^~~~~ /home/kondo/local/usr/local/include/c++/6.0.0/tuple:629:21: note: invalid template non-type parameter test.cpp:6:33: note: candidate: template<class ... _UElements, class _Dummy, typename std::enable_if<((std::_TC<(1ul == sizeof... (_UElements)), int>::_ConstructibleTuple<_UElements ...>() && std::_TC<(1ul == sizeof... (_UElements)), int>::_ImplicitlyConvertibleTuple<_UElements ...>()) && std::_TC<(std::is_same<_Dummy, void>::value && (1ul == 1)), int>::_NonNestedTuple<const tuple<_Elements ...>&>()), bool>::type <anonymous> > constexpr my_tuple<int>::my_tuple(const std::tuple<_Elements ...>&) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: In file included from test.cpp:1:0: /home/kondo/local/usr/local/include/c++/6.0.0/tuple:650:21: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’ bool>::type=true> ^~~~ /home/kondo/local/usr/local/include/c++/6.0.0/tuple:650:21: note: invalid template non-type parameter test.cpp:6:33: note: candidate: template<class ... _UElements, class _Dummy, typename std::enable_if<((std::_TC<(1ul == sizeof... (_UElements)), int>::_ConstructibleTuple<_UElements ...>() && (! std::_TC<(1ul == sizeof... (_UElements)), int>::_ImplicitlyConvertibleTuple<_UElements ...>())) && std::_TC<(std::is_same<_Dummy, void>::value && (1ul == 1)), int>::_NonNestedTuple<const tuple<_Elements ...>&>()), bool>::type <anonymous> > constexpr my_tuple<int>::my_tuple(const std::tuple<_Elements ...>&) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: In file included from test.cpp:1:0: /home/kondo/local/usr/local/include/c++/6.0.0/tuple:662:21: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’ bool>::type=false> ^~~~~ /home/kondo/local/usr/local/include/c++/6.0.0/tuple:662:21: note: invalid template non-type parameter test.cpp:6:33: note: candidate: template<class ... _UElements, class _Dummy, typename std::enable_if<((std::_TC<(1ul == sizeof... (_UElements)), int>::_MoveConstructibleTuple<_UElements ...>() && std::_TC<(1ul == sizeof... (_UElements)), int>::_ImplicitlyMoveConvertibleTuple<_UElements ...>()) && std::_TC<(std::is_same<_Dummy, void>::value && (1ul == 1)), int>::_NonNestedTuple<tuple<_Elements ...>&&>()), bool>::type <anonymous> > constexpr my_tuple<int>::my_tuple(std::tuple<_Elements ...>&&) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: In file included from test.cpp:1:0: /home/kondo/local/usr/local/include/c++/6.0.0/tuple:674:21: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’ bool>::type=true> ^~~~ /home/kondo/local/usr/local/include/c++/6.0.0/tuple:674:21: note: invalid template non-type parameter test.cpp:6:33: note: candidate: template<class ... _UElements, class _Dummy, typename std::enable_if<((std::_TC<(1ul == sizeof... (_UElements)), int>::_MoveConstructibleTuple<_UElements ...>() && (! std::_TC<(1ul == sizeof... (_UElements)), int>::_ImplicitlyMoveConvertibleTuple<_UElements ...>())) && std::_TC<(std::is_same<_Dummy, void>::value && (1ul == 1)), int>::_NonNestedTuple<tuple<_Elements ...>&&>()), bool>::type <anonymous> > constexpr my_tuple<int>::my_tuple(std::tuple<_Elements ...>&&) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: In file included from test.cpp:1:0: /home/kondo/local/usr/local/include/c++/6.0.0/tuple:685:21: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’ bool>::type=false> ^~~~~ /home/kondo/local/usr/local/include/c++/6.0.0/tuple:685:21: note: invalid template non-type parameter test.cpp:6:33: note: candidate: template<class _Alloc> my_tuple<int>::my_tuple(std::allocator_arg_t, const _Alloc&) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: test.cpp:11:24: note: candidate expects 2 arguments, 1 provided my_tuple<int> mt(st); ^ test.cpp:6:33: note: candidate: template<class _Alloc, class _Dummy, typename std::enable_if<(std::_TC<std::is_same<_Dummy, void>::value, int>::_ConstructibleTuple<int>() && std::_TC<std::is_same<_Dummy, void>::value, int>::_ImplicitlyConvertibleTuple<int>()), bool>::type <anonymous> > my_tuple<int>::my_tuple(std::allocator_arg_t, const _Alloc&, const int&) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: test.cpp:11:24: note: candidate expects 3 arguments, 1 provided my_tuple<int> mt(st); ^ test.cpp:6:33: note: candidate: template<class _Alloc, class _Dummy, typename std::enable_if<(std::_TC<std::is_same<_Dummy, void>::value, int>::_ConstructibleTuple<int>() && (! std::_TC<std::is_same<_Dummy, void>::value, int>::_ImplicitlyConvertibleTuple<int>())), bool>::type <anonymous> > my_tuple<int>::my_tuple(std::allocator_arg_t, const _Alloc&, const int&) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: test.cpp:11:24: note: candidate expects 3 arguments, 1 provided my_tuple<int> mt(st); ^ test.cpp:6:33: note: candidate: template<class _Alloc, class ... _UElements, typename std::enable_if<(std::_TC<(1ul == sizeof... (_UElements)), int>::_MoveConstructibleTuple<_UElements ...>() && std::_TC<(1ul == sizeof... (_UElements)), int>::_ImplicitlyMoveConvertibleTuple<_UElements ...>()), bool>::type <anonymous> > my_tuple<int>::my_tuple(std::allocator_arg_t, const _Alloc&, _UElements&& ...) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: test.cpp:11:24: note: candidate expects at least 2 arguments, 1 provided my_tuple<int> mt(st); ^ test.cpp:6:33: note: candidate: template<class _Alloc, class ... _UElements, typename std::enable_if<(std::_TC<(1ul == sizeof... (_UElements)), int>::_MoveConstructibleTuple<_UElements ...>() && (! std::_TC<(1ul == sizeof... (_UElements)), int>::_ImplicitlyMoveConvertibleTuple<_UElements ...>())), bool>::type <anonymous> > my_tuple<int>::my_tuple(std::allocator_arg_t, const _Alloc&, _UElements&& ...) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: test.cpp:11:24: note: candidate expects at least 2 arguments, 1 provided my_tuple<int> mt(st); ^ test.cpp:6:33: note: candidate: template<class _Alloc> my_tuple<int>::my_tuple(std::allocator_arg_t, const _Alloc&, const std::tuple<int>&) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: test.cpp:11:24: note: candidate expects 3 arguments, 1 provided my_tuple<int> mt(st); ^ test.cpp:6:33: note: candidate: template<class _Alloc> my_tuple<int>::my_tuple(std::allocator_arg_t, const _Alloc&, std::tuple<int>&&) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: test.cpp:11:24: note: candidate expects 3 arguments, 1 provided my_tuple<int> mt(st); ^ test.cpp:6:33: note: candidate: template<class _Alloc, class ... _UElements, typename std::enable_if<(std::_TC<(1ul == sizeof... (_UElements)), int>::_ConstructibleTuple<_UElements ...>() && std::_TC<(1ul == sizeof... (_UElements)), int>::_ImplicitlyConvertibleTuple<_UElements ...>()), bool>::type <anonymous> > my_tuple<int>::my_tuple(std::allocator_arg_t, const _Alloc&, const std::tuple<_Elements ...>&) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: test.cpp:11:24: note: candidate expects 3 arguments, 1 provided my_tuple<int> mt(st); ^ test.cpp:6:33: note: candidate: template<class _Alloc, class ... _UElements, typename std::enable_if<(std::_TC<(1ul == sizeof... (_UElements)), int>::_ConstructibleTuple<_UElements ...>() && (! std::_TC<(1ul == sizeof... (_UElements)), int>::_ImplicitlyConvertibleTuple<_UElements ...>())), bool>::type <anonymous> > my_tuple<int>::my_tuple(std::allocator_arg_t, const _Alloc&, const std::tuple<_Elements ...>&) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: test.cpp:11:24: note: candidate expects 3 arguments, 1 provided my_tuple<int> mt(st); ^ test.cpp:6:33: note: candidate: template<class _Alloc, class ... _UElements, typename std::enable_if<(std::_TC<(1ul == sizeof... (_UElements)), int>::_MoveConstructibleTuple<_UElements ...>() && std::_TC<(1ul == sizeof... (_UElements)), int>::_ImplicitlyMoveConvertibleTuple<_UElements ...>()), bool>::type <anonymous> > my_tuple<int>::my_tuple(std::allocator_arg_t, const _Alloc&, std::tuple<_Elements ...>&&) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: test.cpp:11:24: note: candidate expects 3 arguments, 1 provided my_tuple<int> mt(st); ^ test.cpp:6:33: note: candidate: template<class _Alloc, class ... _UElements, typename std::enable_if<(std::_TC<(1ul == sizeof... (_UElements)), int>::_MoveConstructibleTuple<_UElements ...>() && (! std::_TC<(1ul == sizeof... (_UElements)), int>::_ImplicitlyMoveConvertibleTuple<_UElements ...>())), bool>::type <anonymous> > my_tuple<int>::my_tuple(std::allocator_arg_t, const _Alloc&, std::tuple<_Elements ...>&&) using std::tuple<Types...>::tuple; ^~~~~ test.cpp:6:33: note: template argument deduction/substitution failed: test.cpp:11:24: note: candidate expects 3 arguments, 1 provided my_tuple<int> mt(st); ^ test.cpp:4:8: note: candidate: constexpr my_tuple<int>::my_tuple(const my_tuple<int>&) struct my_tuple : std::tuple<Types...> { ^~~~~~~~ test.cpp:4:8: note: no known conversion for argument 1 from ‘std::tuple<int>’ to ‘const my_tuple<int>&’ test.cpp:4:8: note: candidate: constexpr my_tuple<int>::my_tuple(my_tuple<int>&&) test.cpp:4:8: note: no known conversion for argument 1 from ‘std::tuple<int>’ to ‘my_tuple<int>&&’ Note It works on g++ 5.3.0 and clang++ 3.7.1.