Consider the following code:
#include <utility>
#include <vector>
using V = std::vector<int>;
int main() {
std::pair<int, V> p1{1, 2}; // p1.second has 2 elements
std::pair<int, V> p2{1, {2}}; // p2.second has 1 element
std::pair<V, V> p3{2, 2}; // Both vectors have 2 elements
std::pair<V, V> p4{{2}, {2}}; // Both vectors have 1 element
std::pair<V, V> p5{2, {2}}; // Does not compile
// p5.first should have 2 elements, while the other should have 1
}
My main issue is with the last line, p5
, which does not compile with g++-12
but does with g++-10
. I would like to know:
- What has changed that caused this issue?
- Can it be compiled again without having to build the vectors and
copying them in (i.e. not use
V(2)
somewhere)
I have tried playing with std::piecewise_construct
as well but I'm not sure it is the correct solution here.
ERROR:
<source>: In function 'int main()':
<source>:9:30: error: no matching function for call to 'std::pair<std::vector<int>, std::vector<int> >::pair(<brace-enclosed initializer list>)'
9 | std::pair<V, V> p3{2, {2}};
| ^
In file included from /opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/utility:69,
from <source>:1:
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:354:9: note: candidate: 'template<class _U1, class _U2> requires _S_constructible<_U1, _U2>() && _S_dangles<_U1, _U2>() constexpr std::pair<_T1, _T2>::pair(std::pair<_U1, _U2>&&) [with _U2 = _U1; _T1 = std::vector<int>; _T2 = std::vector<int>]' (deleted)
354 | pair(pair<_U1, _U2>&&) = delete;
| ^~~~
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:354:9: note: template argument deduction/substitution failed:
<source>:9:30: note: mismatched types 'std::pair<_T1, _T2>' and 'int'
9 | std::pair<V, V> p3{2, {2}};
| ^
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:345:9: note: candidate: 'template<class _U1, class _U2> requires _S_constructible<_U1, _U2>() && !_S_dangles<_U1, _U2>() constexpr std::pair<_T1, _T2>::pair(std::pair<_U1, _U2>&&) [with _U2 = _U1; _T1 = std::vector<int>; _T2 = std::vector<int>]'
345 | pair(pair<_U1, _U2>&& __p)
| ^~~~
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:345:9: note: template argument deduction/substitution failed:
<source>:9:30: note: mismatched types 'std::pair<_T1, _T2>' and 'int'
9 | std::pair<V, V> p3{2, {2}};
| ^
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:339:9: note: candidate: 'template<class _U1, class _U2> requires _S_constructible<const _U1&, const _U2&>() && _S_dangles<const _U1&, const _U2&>() constexpr std::pair<_T1, _T2>::pair(const std::pair<_U1, _U2>&) [with _U2 = _U1; _T1 = std::vector<int>; _T2 = std::vector<int>]' (deleted)
339 | pair(const pair<_U1, _U2>&) = delete;
| ^~~~
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:339:9: note: template argument deduction/substitution failed:
<source>:9:30: note: mismatched types 'const std::pair<_T1, _T2>' and 'int'
9 | std::pair<V, V> p3{2, {2}};
| ^
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:330:9: note: candidate: 'template<class _U1, class _U2> requires _S_constructible<const _U1&, const _U2&>() && !_S_dangles<_U1, _U2>() constexpr std::pair<_T1, _T2>::pair(const std::pair<_U1, _U2>&) [with _U2 = _U1; _T1 = std::vector<int>; _T2 = std::vector<int>]'
330 | pair(const pair<_U1, _U2>& __p)
| ^~~~
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:330:9: note: template argument deduction/substitution failed:
<source>:9:30: note: mismatched types 'const std::pair<_T1, _T2>' and 'int'
9 | std::pair<V, V> p3{2, {2}};
| ^
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:323:9: note: candidate: 'template<class _U1, class _U2> requires _S_constructible<_U1, _U2>() && _S_dangles<_U1, _U2>() constexpr std::pair<_T1, _T2>::pair(_U1&&, _U2&&) [with _U2 = _U1; _T1 = std::vector<int>; _T2 = std::vector<int>]' (deleted)
323 | pair(_U1&&, _U2&&) = delete;
| ^~~~
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:323:9: note: template argument deduction/substitution failed:
<source>:9:30: note: couldn't deduce template parameter '_U2'
9 | std::pair<V, V> p3{2, {2}};
| ^
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:315:9: note: candidate: 'template<class _U1, class _U2> requires _S_constructible<_U1, _U2>() && !_S_dangles<_U1, _U2>() constexpr std::pair<_T1, _T2>::pair(_U1&&, _U2&&) [with _U2 = _U1; _T1 = std::vector<int>; _T2 = std::vector<int>]'
315 | pair(_U1&& __x, _U2&& __y)
| ^~~~
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:315:9: note: template argument deduction/substitution failed:
<source>:9:30: note: couldn't deduce template parameter '_U2'
9 | std::pair<V, V> p3{2, {2}};
| ^
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:238:9: note: candidate: 'template<class ... _Args1, long unsigned int ..._Indexes1, class ... _Args2, long unsigned int ..._Indexes2> constexpr std::pair<_T1, _T2>::pair(std::tuple<_Args1 ...>&, std::tuple<_Args2 ...>&, std::_Index_tuple<_Indexes1 ...>, std::_Index_tuple<_Indexes2 ...>) [with _Args1 = {_Args1 ...}; long unsigned int ..._Indexes1 = {_Indexes1 ...}; _Args2 = {_Args2 ...}; long unsigned int ..._Indexes2 = {_Indexes2 ...}; _T1 = std::vector<int>; _T2 = std::vector<int>]'
238 | pair(tuple<_Args1...>&, tuple<_Args2...>&,
| ^~~~
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:238:9: note: template argument deduction/substitution failed:
<source>:9:30: note: mismatched types 'std::tuple<_UTypes ...>' and 'int'
9 | std::pair<V, V> p3{2, {2}};
| ^
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:202:9: note: candidate: 'template<class ... _Args1, class ... _Args2> constexpr std::pair<_T1, _T2>::pair(std::piecewise_construct_t, std::tuple<_Args1 ...>, std::tuple<_Args2 ...>) [with _Args1 = {_Args1 ...}; _Args2 = {_Args2 ...}; _T1 = std::vector<int>; _T2 = std::vector<int>]'
202 | pair(piecewise_construct_t, tuple<_Args1...>, tuple<_Args2...>);
| ^~~~
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:202:9: note: template argument deduction/substitution failed:
<source>:9:30: note: candidate expects 3 arguments, 2 provided
9 | std::pair<V, V> p3{2, {2}};
| ^
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:305:7: note: candidate: 'constexpr std::pair<_T1, _T2>::pair(const _T1&, const _T2&) requires _S_constructible<const _T1&, const _T2&>() [with _T1 = std::vector<int>; _T2 = std::vector<int>]'
305 | pair(const _T1& __x, const _T2& __y)
| ^~~~
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:305:23: note: no known conversion for argument 1 from 'int' to 'const std::vector<int>&'
305 | pair(const _T1& __x, const _T2& __y)
| ~~~~~~~~~~~^~~
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:249:7: note: candidate: 'constexpr std::pair<_T1, _T2>::pair() requires (is_default_constructible_v<_T1>) && (is_default_constructible_v<_T2>) [with _T1 = std::vector<int>; _T2 = std::vector<int>]'
249 | pair()
| ^~~~
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:249:7: note: candidate expects 0 arguments, 2 provided
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:198:17: note: candidate: 'constexpr std::pair<_T1, _T2>::pair(std::pair<_T1, _T2>&&) [with _T1 = std::vector<int>; _T2 = std::vector<int>]'
198 | constexpr pair(pair&&) = default; ///< Move constructor
| ^~~~
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:198:17: note: candidate expects 1 argument, 2 provided
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:197:17: note: candidate: 'constexpr std::pair<_T1, _T2>::pair(const std::pair<_T1, _T2>&) [with _T1 = std::vector<int>; _T2 = std::vector<int>]'
197 | constexpr pair(const pair&) = default; ///< Copy constructor
| ^~~~
/opt/compiler-explorer/gcc-trunk-20230315/include/c++/13.0.1/bits/stl_pair.h:197:17: note: candidate expects 1 argument, 2 provided
Compiler returned: 1
std::pair<int, V> p2{1, {2}};
will not build thevector
in-place. It will create avector
and move it into thepair
. – Uninstructed{}
) can never be deduced by a template. It will not deduce to aninitializer_list
or anything else. If you use a{}
in a function parameter list, that argument will never participate in template argument deduction. Therefore, it will select constructor 2, witht2
being initialized from the braced-init-list and then copied in. – Uninstructedvector
norpair<int, vector<int>>
are aggregates. – Uninstructedpiecewise_construct
plus an explicitinitializer_list
as the second parameter, correct? If so, at least one of my questions is answered :) – Wilcox