Related
I realize nested std::any's are a bad idea. Nevertheless, I encountered something that's making me scratch my head and I'm just trying to understand why the compiler is choking. Consider the following line of code (assuming that the arg variable is a std::any containing another std::any):
auto result = std::any_cast<std::any>(arg);
That line compiles just fine. Now, consider this line, where I have a std::any containing a std::tuple that contains another std::any:
auto result = std::any_cast<std::tuple<std::any>>(arg);
Now, the compiler blows up. These are the errors I get:
In file included from /home/james/git/trogdor-pp/src/core/event/triggers/luaeventtrigger.cpp:1:
In file included from /home/james/git/trogdor-pp/src/core/include/trogdor/game.h:5:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:37:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/new:40:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/exception:144:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/nested_exception.h:40:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/move.h:55:
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:132:31: error: no member named 'value' in 'std::is_copy_constructible<std::tuple<std::any> >'
: public conditional<_B1::value, _B2, _B1>::type
~~~~~^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:170:17: note: in instantiation of template class 'std::__and_<std::is_copy_constructible<std::tuple<std::any> >, std::is_constructible<std::tuple<std::any>, const std::tuple<std::any> &> >' requested here
enable_if<__and_<is_copy_constructible<_Tp>,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:175:5: note: in instantiation of template type alias '__any_constructible' requested here
using __any_constructible_t =
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:181:56: note: in instantiation of template type alias '__any_constructible_t' requested here
__any_constructible_t<_Tp, _ValueType&&> = true,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:183:7: note: while substituting prior template arguments into non-type template parameter [with _ValueType = const std::tuple<std::any> &, _Tp = std::tuple<std::any>, _Mgr = std::any::_Manager_external<std::tuple<std::any> >]
any(_ValueType&& __value)
^~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:884:56: note: while substituting deduced template arguments into function template 'any' [with _ValueType = const std::tuple<std::any> &, _Tp = (no value), _Mgr = (no value), $3 = (no value), $4 = (no value)]
: public __bool_constant<__is_constructible(_Tp, _Args...)>
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:884:32: note: (skipping 2 contexts in backtrace; use -ftemplate-backtrace-limit=0 to see all)
: public __bool_constant<__is_constructible(_Tp, _Args...)>
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:908:14: note: in instantiation of template class 'std::__is_copy_constructible_impl<std::tuple<std::any>, true>' requested here
: public __is_copy_constructible_impl<_Tp>
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:109:14: note: in instantiation of template class 'std::is_copy_constructible<std::tuple<std::any> >' requested here
: public conditional<_B1::value, _B1, _B2>::type
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:358:16: note: in instantiation of template class 'std::__or_<std::is_reference<std::tuple<std::any> >, std::is_copy_constructible<std::tuple<std::any> > >' requested here
{ return __or_<is_reference<_Tp>, is_copy_constructible<_Tp>>::value; }
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:481:26: note: in instantiation of function template specialization 'std::any::__is_valid_cast<std::tuple<std::any> >' requested here
static_assert(any::__is_valid_cast<_ValueType>(),
^
/home/james/git/trogdor-pp/src/core/event/triggers/luaeventtrigger.cpp:42:32: note: in instantiation of function template specialization 'std::any_cast<std::tuple<std::any> >' requested here
auto arg = std::any_cast<std::tuple<std::any>>(a);
^
In file included from /home/james/git/trogdor-pp/src/core/event/triggers/luaeventtrigger.cpp:1:
In file included from /home/james/git/trogdor-pp/src/core/include/trogdor/game.h:5:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:37:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/new:40:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/exception:144:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/nested_exception.h:40:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/move.h:55:
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:137:31: error: no member named 'value' in 'std::is_copy_constructible<std::tuple<std::any> >'
: public conditional<_B1::value, __and_<_B2, _B3, _Bn...>, _B1>::type
~~~~~^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:150:37: note: in instantiation of template class 'std::__and_<std::is_copy_constructible<std::tuple<std::any> >, std::__not_<std::is_constructible<std::tuple<std::any>, const std::tuple<std::any> &> >, std::__not_<std::__is_in_place_type<std::tuple<std::any> > > >' requested here
inline constexpr bool __and_v = __and_<_Bn...>::value;
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:192:27: note: in instantiation of variable template specialization 'std::__and_v<std::is_copy_constructible<std::tuple<std::any> >, std::__not_<std::is_constructible<std::tuple<std::any>, const std::tuple<std::any> &> >, std::__not_<std::__is_in_place_type<std::tuple<std::any> > > >' requested here
enable_if_t<__and_v<is_copy_constructible<_Tp>,
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:196:7: note: while substituting prior template arguments into non-type template parameter [with _ValueType = const std::tuple<std::any> &, _Tp = std::tuple<std::any>, _Mgr = std::any::_Manager_external<std::tuple<std::any> >]
any(_ValueType&& __value)
^~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:884:56: note: while substituting deduced template arguments into function template 'any' [with _ValueType = const std::tuple<std::any> &, _Tp = (no value), _Mgr = (no value), $3 = (no value)]
: public __bool_constant<__is_constructible(_Tp, _Args...)>
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:884:32: note: while substituting deduced template arguments into function template 'tuple' [with _Dummy = (no value), $1 = (no value)]
: public __bool_constant<__is_constructible(_Tp, _Args...)>
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:902:14: note: (skipping 1 context in backtrace; use -ftemplate-backtrace-limit=0 to see all)
: public is_constructible<_Tp, const _Tp&>
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:908:14: note: in instantiation of template class 'std::__is_copy_constructible_impl<std::tuple<std::any>, true>' requested here
: public __is_copy_constructible_impl<_Tp>
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/type_traits:109:14: note: in instantiation of template class 'std::is_copy_constructible<std::tuple<std::any> >' requested here
: public conditional<_B1::value, _B1, _B2>::type
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:358:16: note: in instantiation of template class 'std::__or_<std::is_reference<std::tuple<std::any> >, std::is_copy_constructible<std::tuple<std::any> > >' requested here
{ return __or_<is_reference<_Tp>, is_copy_constructible<_Tp>>::value; }
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/any:481:26: note: in instantiation of function template specialization 'std::any::__is_valid_cast<std::tuple<std::any> >' requested here
static_assert(any::__is_valid_cast<_ValueType>(),
^
/home/james/git/trogdor-pp/src/core/event/triggers/luaeventtrigger.cpp:42:32: note: in instantiation of function template specialization 'std::any_cast<std::tuple<std::any> >' requested here
auto arg = std::any_cast<std::tuple<std::any>>(a);
I'm having a hard time unpacking all of that and figuring out what's wrong and how I can fix it.
EDIT: we've discovered in the comments that this code does not compile under G++ 9 and below, but compiles on G++ 10 and above, and also fails on clang 10 and below, but compiles on clang 11 and above. Does anybody have any guesses as to why this might be the case?
The key part is error: no member named 'value' in 'std::is_copy_constructible<std::tuple<std::any> >'
This is the compiler's way of complaining that the indicated object, the std::tuple, is not copy-constructible.
Your gcc does not believe, apparently, that std::tuplestd::any is copy-constructible. A tuple, in of itself, should be copy constructible if everything in the tuple is copy-constructible. Given that std::any is C++17, and gcc 9's C++17 support is incomplete, at least incomplete insofar as this part of C++17 goes (gcc 11's feature list still includes some C++17 features).
i was trying to solve a competitive programming problem (on AtCoder) and i wanted to use priority queue, but then i got some problem.
i wrote the code below but when i tried to compile that, i got error messages that said "no matching member function for call to 'push' "
(the entire error messages are shown below)
i have no idea why this is happening, and i tried it on AtCoder Code Test online judge.
https://atcoder.jp/contests/abc176/custom_test
it worked completely fine on the online judge.
adding to that, i talked about this problem with my friend and he said the code worked just fine on his environment (he uses Windows).
Here is the code.
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <sstream>
#include <set>
#include <map>
#include <vector>
#include <list>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <string>
#include <stack>
#include <queue>
#include <bitset>
#include <cassert>
#include <iomanip>
#include <ctime>
#include <complex>
using namespace std;
int main()
{
priority_queue<array<int, 3>> pq;
pq.push({0, 1, 4});
}
i wrote the code and build it with vscode (Version: 1.49.1), and this is the error messages i got at that time.
> Executing task: g++ -std=c++14 -g -O2 abc176_d_11.cpp -o abc176_d_11 <
abc176_d_11.cpp:27:8: error: no matching member function for call to 'push'
pq.push({0, 1, 4});
~~~^~~~
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/queue:536:10: note: candidate function not viable: cannot convert initializer list argument to
'const std::__1::priority_queue<std::__1::array<int, 3>, std::__1::vector<std::__1::array<int, 3>, std::__1::allocator<std::__1::array<int, 3> > >,
std::__1::less<std::__1::array<int, 3> > >::value_type' (aka 'const std::__1::array<int, 3>')
void push(const value_type& __v);
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/queue:539:10: note: candidate function not viable: cannot convert initializer list argument to
'std::__1::priority_queue<std::__1::array<int, 3>, std::__1::vector<std::__1::array<int, 3>, std::__1::allocator<std::__1::array<int, 3> > >,
std::__1::less<std::__1::array<int, 3> > >::value_type' (aka 'std::__1::array<int, 3>')
void push(value_type&& __v);
^
In file included from abc176_d_11.cpp:8:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:426:68: error: implicit instantiation of undefined template 'std::__1::array<int, 3>'
__alloc_traits::destroy(__alloc(), _VSTD::__to_raw_pointer(--__soon_to_be_end));
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:369:29: note: in instantiation of member function
'std::__1::__vector_base<std::__1::array<int, 3>, std::__1::allocator<std::__1::array<int, 3> > >::__destruct_at_end' requested here
void clear() _NOEXCEPT {__destruct_at_end(__begin_);}
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:463:9: note: in instantiation of member function
'std::__1::__vector_base<std::__1::array<int, 3>, std::__1::allocator<std::__1::array<int, 3> > >::clear' requested here
clear();
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:495:5: note: in instantiation of member function
'std::__1::__vector_base<std::__1::array<int, 3>, std::__1::allocator<std::__1::array<int, 3> > >::~__vector_base' requested here
vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/queue:447:11: note: in instantiation of member function 'std::__1::vector<std::__1::array<int,
3>, std::__1::allocator<std::__1::array<int, 3> > >::vector' requested here
: c(), comp() {}
^
abc176_d_11.cpp:26:35: note: in instantiation of member function 'std::__1::priority_queue<std::__1::array<int, 3>, std::__1::vector<std::__1::array<int,
3>, std::__1::allocator<std::__1::array<int, 3> > >, std::__1::less<std::__1::array<int, 3> > >::priority_queue' requested here
priority_queue<array<int, 3>> pq;
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__tuple:219:64: note: template is declared here
template <class _Tp, size_t _Size> struct _LIBCPP_TEMPLATE_VIS array;
^
In file included from abc176_d_11.cpp:3:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/iostream:37:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/ios:215:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__locale:14:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/string:504:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/string_view:175:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__string:56:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/algorithm:643:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:1816:55: error: implicit instantiation of undefined template 'std::__1::array<int, 3>'
{_VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));}
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:1554:14: note: in instantiation of member function
'std::__1::allocator<std::__1::array<int, 3> >::deallocate' requested here
{__a.deallocate(__p, __n);}
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:464:25: note: in instantiation of member function
'std::__1::allocator_traits<std::__1::allocator<std::__1::array<int, 3> > >::deallocate' requested here
__alloc_traits::deallocate(__alloc(), __begin_, capacity());
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:495:5: note: in instantiation of member function
'std::__1::__vector_base<std::__1::array<int, 3>, std::__1::allocator<std::__1::array<int, 3> > >::~__vector_base' requested here
vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/queue:447:11: note: in instantiation of member function 'std::__1::vector<std::__1::array<int,
3>, std::__1::allocator<std::__1::array<int, 3> > >::vector' requested here
: c(), comp() {}
^
abc176_d_11.cpp:26:35: note: in instantiation of member function 'std::__1::priority_queue<std::__1::array<int, 3>, std::__1::vector<std::__1::array<int,
3>, std::__1::allocator<std::__1::array<int, 3> > >, std::__1::less<std::__1::array<int, 3> > >::priority_queue' requested here
priority_queue<array<int, 3>> pq;
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__tuple:219:64: note: template is declared here
template <class _Tp, size_t _Size> struct _LIBCPP_TEMPLATE_VIS array;
^
In file included from abc176_d_11.cpp:8:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:372:52: error: implicit instantiation of undefined template 'std::__1::array<int, 3>'
{return static_cast<size_type>(__end_cap() - __begin_);}
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:464:57: note: in instantiation of member function
'std::__1::__vector_base<std::__1::array<int, 3>, std::__1::allocator<std::__1::array<int, 3> > >::capacity' requested here
__alloc_traits::deallocate(__alloc(), __begin_, capacity());
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:495:5: note: in instantiation of member function
'std::__1::__vector_base<std::__1::array<int, 3>, std::__1::allocator<std::__1::array<int, 3> > >::~__vector_base' requested here
vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/queue:447:11: note: in instantiation of member function 'std::__1::vector<std::__1::array<int,
3>, std::__1::allocator<std::__1::array<int, 3> > >::vector' requested here
: c(), comp() {}
^
abc176_d_11.cpp:26:35: note: in instantiation of member function 'std::__1::priority_queue<std::__1::array<int, 3>, std::__1::vector<std::__1::array<int,
3>, std::__1::allocator<std::__1::array<int, 3> > >, std::__1::less<std::__1::array<int, 3> > >::priority_queue' requested here
priority_queue<array<int, 3>> pq;
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__tuple:219:64: note: template is declared here
template <class _Tp, size_t _Size> struct _LIBCPP_TEMPLATE_VIS array;
^
In file included from abc176_d_11.cpp:8:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:872:54: error: implicit instantiation of undefined template 'std::__1::array<int, 3>'
__annotate_contiguous_container(data(), data() + capacity(),
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:551:9: note: in instantiation of member function 'std::__1::vector<std::__1::array<int,
3>, std::__1::allocator<std::__1::array<int, 3> > >::__annotate_delete' requested here
__annotate_delete();
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/queue:427:28: note: in instantiation of member function 'std::__1::vector<std::__1::array<int,
3>, std::__1::allocator<std::__1::array<int, 3> > >::~vector' requested here
class _LIBCPP_TEMPLATE_VIS priority_queue
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__tuple:219:64: note: template is declared here
template <class _Tp, size_t _Size> struct _LIBCPP_TEMPLATE_VIS array;
^
5 errors generated.
The terminal process "/usr/local/bin/bash '-c', 'g++ -std=c++14 -g -O2 abc176_d_11.cpp -o abc176_d_11'" terminated with exit code: 1.
Terminal will be reused by tasks, press any key to close it.
after that i tried to compile it from normal (i mean, not within vscode) terminal (i used iTerm) but got kinda same sort of error messages.
here is that error messages I got when I tried to compile the code on terminal.
[my_computer_name]#MacBook-Pro:~/coder$ g++ abc176_d_11.cpp
abc176_d_11.cpp:27:8: error: no matching member function for call to 'push'
pq.push({0, 1, 4});
~~~^~~~
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/queue:536:10: note: candidate function
not viable: cannot convert initializer list argument to 'const
std::__1::priority_queue<std::__1::array<int, 3>, std::__1::vector<std::__1::array<int, 3>,
std::__1::allocator<std::__1::array<int, 3> > >, std::__1::less<std::__1::array<int, 3> >
>::value_type' (aka 'const std::__1::array<int, 3>')
void push(const value_type& __v);
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/queue:539:10: note: candidate function
not viable: cannot convert initializer list argument to
'std::__1::priority_queue<std::__1::array<int, 3>, std::__1::vector<std::__1::array<int, 3>,
std::__1::allocator<std::__1::array<int, 3> > >, std::__1::less<std::__1::array<int, 3> >
>::value_type' (aka 'std::__1::array<int, 3>')
void push(value_type&& __v);
^
In file included from abc176_d_11.cpp:8:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:426:68: error: implicit
instantiation of undefined template 'std::__1::array<int, 3>'
__alloc_traits::destroy(__alloc(), _VSTD::__to_raw_pointer(--__soon_to_be_end));
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:369:29: note: in instantiation of
member function 'std::__1::__vector_base<std::__1::array<int, 3>,
std::__1::allocator<std::__1::array<int, 3> > >::__destruct_at_end' requested here
void clear() _NOEXCEPT {__destruct_at_end(__begin_);}
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:463:9: note: in instantiation of
member function 'std::__1::__vector_base<std::__1::array<int, 3>,
std::__1::allocator<std::__1::array<int, 3> > >::clear' requested here
clear();
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:495:5: note: in instantiation of
member function 'std::__1::__vector_base<std::__1::array<int, 3>,
std::__1::allocator<std::__1::array<int, 3> > >::~__vector_base' requested here
vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/queue:447:11: note: in instantiation of
member function 'std::__1::vector<std::__1::array<int, 3>,
std::__1::allocator<std::__1::array<int, 3> > >::vector' requested here
: c(), comp() {}
^
abc176_d_11.cpp:26:35: note: in instantiation of member function
'std::__1::priority_queue<std::__1::array<int, 3>, std::__1::vector<std::__1::array<int, 3>,
std::__1::allocator<std::__1::array<int, 3> > >, std::__1::less<std::__1::array<int, 3> >
>::priority_queue' requested here
priority_queue<array<int, 3>> pq;
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__tuple:219:64: note: template is
declared here
template <class _Tp, size_t _Size> struct _LIBCPP_TEMPLATE_VIS array;
^
In file included from abc176_d_11.cpp:3:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/iostream:37:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/ios:215:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__locale:14:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/string:504:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/string_view:175:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__string:56:
In file included from /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/algorithm:643:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:1816:55: error: implicit
instantiation of undefined template 'std::__1::array<int, 3>'
{_VSTD::__libcpp_deallocate((void*)__p, __n * sizeof(_Tp), _LIBCPP_ALIGNOF(_Tp));}
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/memory:1554:14: note: in instantiation
of member function 'std::__1::allocator<std::__1::array<int, 3> >::deallocate' requested here
{__a.deallocate(__p, __n);}
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:464:25: note: in instantiation of
member function 'std::__1::allocator_traits<std::__1::allocator<std::__1::array<int, 3> >
>::deallocate' requested here
__alloc_traits::deallocate(__alloc(), __begin_, capacity());
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:495:5: note: in instantiation of
member function 'std::__1::__vector_base<std::__1::array<int, 3>,
std::__1::allocator<std::__1::array<int, 3> > >::~__vector_base' requested here
vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/queue:447:11: note: in instantiation of
member function 'std::__1::vector<std::__1::array<int, 3>,
std::__1::allocator<std::__1::array<int, 3> > >::vector' requested here
: c(), comp() {}
^
abc176_d_11.cpp:26:35: note: in instantiation of member function
'std::__1::priority_queue<std::__1::array<int, 3>, std::__1::vector<std::__1::array<int, 3>,
std::__1::allocator<std::__1::array<int, 3> > >, std::__1::less<std::__1::array<int, 3> >
>::priority_queue' requested here
priority_queue<array<int, 3>> pq;
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__tuple:219:64: note: template is
declared here
template <class _Tp, size_t _Size> struct _LIBCPP_TEMPLATE_VIS array;
^
In file included from abc176_d_11.cpp:8:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:372:52: error: implicit
instantiation of undefined template 'std::__1::array<int, 3>'
{return static_cast<size_type>(__end_cap() - __begin_);}
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:464:57: note: in instantiation of
member function 'std::__1::__vector_base<std::__1::array<int, 3>,
std::__1::allocator<std::__1::array<int, 3> > >::capacity' requested here
__alloc_traits::deallocate(__alloc(), __begin_, capacity());
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:495:5: note: in instantiation of
member function 'std::__1::__vector_base<std::__1::array<int, 3>,
std::__1::allocator<std::__1::array<int, 3> > >::~__vector_base' requested here
vector() _NOEXCEPT_(is_nothrow_default_constructible<allocator_type>::value)
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/queue:447:11: note: in instantiation of
member function 'std::__1::vector<std::__1::array<int, 3>,
std::__1::allocator<std::__1::array<int, 3> > >::vector' requested here
: c(), comp() {}
^
abc176_d_11.cpp:26:35: note: in instantiation of member function
'std::__1::priority_queue<std::__1::array<int, 3>, std::__1::vector<std::__1::array<int, 3>,
std::__1::allocator<std::__1::array<int, 3> > >, std::__1::less<std::__1::array<int, 3> >
>::priority_queue' requested here
priority_queue<array<int, 3>> pq;
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__tuple:219:64: note: template is
declared here
template <class _Tp, size_t _Size> struct _LIBCPP_TEMPLATE_VIS array;
^
In file included from abc176_d_11.cpp:8:
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:872:54: error: implicit
instantiation of undefined template 'std::__1::array<int, 3>'
__annotate_contiguous_container(data(), data() + capacity(),
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/vector:551:9: note: in instantiation of
member function 'std::__1::vector<std::__1::array<int, 3>,
std::__1::allocator<std::__1::array<int, 3> > >::__annotate_delete' requested here
__annotate_delete();
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/queue:427:28: note: in instantiation of
member function 'std::__1::vector<std::__1::array<int, 3>,
std::__1::allocator<std::__1::array<int, 3> > >::~vector' requested here
class _LIBCPP_TEMPLATE_VIS priority_queue
^
/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/__tuple:219:64: note: template is
declared here
template <class _Tp, size_t _Size> struct _LIBCPP_TEMPLATE_VIS array;
^
5 errors generated.
Here is my environment.
MacBook Pro
macOS Catalina
Version 10.15.5
i'm still a beginner on programming, espicially c++, and if my question doesn't make sense or seems silly, i want to apologize in advance.
my english is not good too.
i would be so grateful if i could have your help.
thank you.
The key error message is this:
implicit instantiation of undefined template 'std::__1::array<int, 3>'
This says that the array is undefined. So in your environment you need #include<array> explicitly.
The minimum working example is thus this:
#include <array>
#include <queue>
using namespace std;
int main()
{
priority_queue<array<int, 3>> pq;
pq.push({0, 1, 4});
}
Notice that I explicitly include <array> and <queue> (in alphabetical order). This is a golden standard: if you use a library, include it directly, do not count on indirect includes. Keep some order in you include list. Do not include what you need not.
Do you have an ancient version of g++? I tried compiling your code as far back as 4.8.1 (from 2013) and it worked in c++11 mode. In older versions than that, it didn't know some of the headers.
(Current version is 10.2.0)
I suggest you try playing with your code on Compiler Explorer. It gives you access to online versions of g++, clang, msvc++, and others, going back for many years over many versions, without any hassle of setup or installing anything.
Here's your code with g++ 4.8:
https://godbolt.org/z/5TTjqd
My code use templates heavily. I have a number of overloaded functions
auto operator>>(byte_vector_view&bvv, Type&&) ->byte_vector_view&;
This works fine until unknown by this function family type is passed to function:
bvv >> my_custom;
User should simply see one error message:
There no implementation for operator>>(byte_vector_view&bvv, my_custom_type&)
instead we see a very long manuscript:
how to put this under spoiler?
itm.cpp:184:18: error: invalid operands to binary expression ('byte_vector_view' and 'named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >')
((bvv>>elements),...);
~~~^ ~~~~~~~~
/Library/Developer/CommandLineTools/usr/include/c++/v1/type_traits:4345:23: note: in instantiation of function template specialization 'operator>>(byte_vector_view &, std::__1::tuple<named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > &)::(anonymous class)::operator()<named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >' requested here
_LIBCPP_INVOKE_RETURN(_VSTD::forward<_Fp>(__f)(_VSTD::forward<_Args>(__args)...))
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/__config:508:15: note: expanded from macro '_VSTD'
#define _VSTD std::_LIBCPP_NAMESPACE
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/tuple:1375:5: note: while substituting deduced template arguments into function template '__invoke_constexpr' [with _Fp = (lambda at itm.cpp:183:9), _Args = <named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > &>]
_VSTD::__invoke_constexpr(
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/__config:508:15: note: expanded from macro '_VSTD'
#define _VSTD std::_LIBCPP_NAMESPACE
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/tuple:1372:26: note: in instantiation of exception specification for '__apply_tuple_impl<(lambda at itm.cpp:183:9), std::__1::tuple<named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > &, 0>' requested here
constexpr decltype(auto) __apply_tuple_impl(_Fn && __f, _Tuple && __t,
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/tuple:1384:12: note: in instantiation of function template specialization 'std::__1::__apply_tuple_impl<(lambda at itm.cpp:183:9), std::__1::tuple<named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > &, 0>' requested here
_VSTD::__apply_tuple_impl(
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/tuple:1382:26: note: in instantiation of exception specification for 'apply<(lambda at itm.cpp:183:9), std::__1::tuple<named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > &>' requested here
constexpr decltype(auto) apply(_Fn && __f, _Tuple && __t)
^
itm.cpp:182:5: note: in instantiation of function template specialization 'std::__1::apply<(lambda at itm.cpp:183:9), std::__1::tuple<named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > &>' requested here
apply(
^
itm.cpp:461:20: note: in instantiation of function template specialization 'operator>><std::__1::tuple<named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >' requested here
bvv>>tvs;
^
itm.cpp:427:12: note: in instantiation of member function 'make_converter(bool, std::__1::tuple<named_value<ringnet::proto::opcode>, named_value<command_address> > &&, named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > &&)::Ret::from_byte_vector_view' requested here
struct Ret:converter_virtual{
^
itm.cpp:537:12: note: in instantiation of function template specialization 'make_converter<std::__1::tuple<named_value<ringnet::proto::opcode>, named_value<command_address> >, named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >' requested here
return make_converter(false,forward<Prefix>(prefix),forward<Ts>(values)...);
^
itm.cpp:931:18: note: in instantiation of function template specialization 'make_converter<std::__1::tuple<named_value<ringnet::proto::opcode>, named_value<command_address> >, named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >' requested here
/*response*/make_converter(
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/type_traits:4840:3: note: candidate function template not viable: no known conversion from 'byte_vector_view' to 'std::byte' for 1st argument
operator>> (byte __lhs, _Integer __shift) noexcept
^
itm.cpp:147:19: note: candidate function not viable: no known conversion from 'named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >' to 'uint8_t &' (aka 'unsigned char &') for 2nd argument
byte_vector_view& operator>>(byte_vector_view&bvv, uint8_t&ui8){
^
itm.cpp:151:19: note: candidate function not viable: no known conversion from 'named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >' to 'std::__1::string &' (aka 'basic_string<char, char_traits<char>, allocator<char> > &') for 2nd argument
byte_vector_view& operator>>(byte_vector_view&bvv, string&str){
^
itm.cpp:156:19: note: candidate function not viable: no known conversion from 'named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >' to 'named_value<std::__1::string> &' (aka 'named_value<basic_string<char, char_traits<char>, allocator<char> > > &') for 2nd argument
byte_vector_view& operator>>(byte_vector_view&bvv, named_value<string>&av){
^
itm.cpp:161:6: note: candidate template ignored: requirement 'is_integral_v<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > || is_same_v<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, ringnet::proto::opcode> || is_same_v<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >, command_address>' was not satisfied [with T = std::__1::vector<unsigned char, std::__1::allocator<unsigned char> >]
auto operator>>(byte_vector_view&bvv, named_value<T>&av) ->enable_if_t<is_integral_v<T> || is_same_v<T,opcode> || is_same_v<T,command_address>, byte_vector_view&>{
^
itm.cpp:181:6: note: candidate template ignored: requirement 'is_tuple<named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >' was not satisfied [with TupleT = named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > >]
auto operator>>(byte_vector_view&bvv, TupleT&tu) ->enable_if_t<is_tuple<TupleT>,byte_vector_view&> {
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/istream:521:1: note: candidate template ignored: could not match 'basic_istream<type-parameter-0-0, type-parameter-0-1>' against 'byte_vector_view'
operator>>(basic_istream<_CharT, _Traits>& __is, _CharT* __s)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/istream:570:1: note: candidate template ignored: could not match 'basic_istream<char, type-parameter-0-0>' against 'byte_vector_view'
operator>>(basic_istream<char, _Traits>& __is, unsigned char* __s)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/istream:578:1: note: candidate template ignored: could not match 'basic_istream<char, type-parameter-0-0>' against 'byte_vector_view'
operator>>(basic_istream<char, _Traits>& __is, signed char* __s)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/istream:585:1: note: candidate template ignored: could not match 'basic_istream<type-parameter-0-0, type-parameter-0-1>' against 'byte_vector_view'
operator>>(basic_istream<_CharT, _Traits>& __is, _CharT& __c)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/istream:613:1: note: candidate template ignored: could not match 'basic_istream<char, type-parameter-0-0>' against 'byte_vector_view'
operator>>(basic_istream<char, _Traits>& __is, unsigned char& __c)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/istream:621:1: note: candidate template ignored: could not match 'basic_istream<char, type-parameter-0-0>' against 'byte_vector_view'
operator>>(basic_istream<char, _Traits>& __is, signed char& __c)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/istream:1219:1: note: candidate template ignored: could not match 'basic_istream<type-parameter-0-0, type-parameter-0-1>' against 'byte_vector_view'
operator>>(basic_istream<_CharT, _Traits>&& __is, _Tp&& __x)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/istream:1287:1: note: candidate template ignored: could not match 'basic_istream<type-parameter-0-0, type-parameter-0-1>' against 'byte_vector_view'
operator>>(basic_istream<_CharT, _Traits>& __is,
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/istream:1419:1: note: candidate template ignored: could not match 'basic_istream<type-parameter-0-0, type-parameter-0-1>' against 'byte_vector_view'
operator>>(basic_istream<_CharT, _Traits>& __is, bitset<_Size>& __x)
^
/Library/Developer/CommandLineTools/usr/include/c++/v1/iomanip:302:1: note: candidate template ignored: could not match 'basic_istream<type-parameter-0-0, type-parameter-0-1>' against 'byte_vector_view'
operator>>(basic_istream<_CharT, _Traits>& __is, const __iom_t7<_MoneyT>& __x)
It's hard to read and understand where is the problem exactly and therefore hard to fix the problem
Need more clear explanation
I found one straightforward way to suppress excess output:
template<typename UnknownType>
auto operator>>(byte_vector_view&bvv, UnknownType&&) ->byte_vector_view& {
static_assert(false);
return bvv;
}
With it compiler gives a quiet short error message, too short:
itm.cpp:192:5: error: static_assert failed
static_assert(false);
^ ~~~~~
1 error generated.
I'd like to see in which function the error appeared and a trace how compiler come there:
template<typename UnknownType>
auto operator>>(byte_vector_view&bvv, UnknownType&&) ->byte_vector_view& {
static_assert(false&&__PRETTY_FUNCTION__);
return bvv;
}
itm.cpp:192:5: error: static_assert failed
static_assert(false && __PRETTY_FUNCTION__);
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
itm.cpp:184:18: note: in instantiation of function template specialization 'operator>><named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > &>' requested here
((bvv>>elements),...);
^
itm.cpp:461:20: note: in instantiation of function template specialization 'operator>><std::__1::tuple<named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > > >' requested here
bvv>>tvs;
^
itm.cpp:427:12: note: in instantiation of member function 'make_converter(bool, std::__1::tuple<named_value<ringnet::proto::opcode>, named_value<command_address> > &&, named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > &&)::Ret::from_byte_vector_view' requested here
struct Ret:converter_virtual{
^
itm.cpp:537:12: note: in instantiation of function template specialization 'make_converter<std::__1::tuple<named_value<ringnet::proto::opcode>, named_value<command_address> >, named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >' requested here
return make_converter(false,forward<Prefix>(prefix),forward<Ts>(values)...);
^
itm.cpp:931:18: note: in instantiation of function template specialization 'make_converter<std::__1::tuple<named_value<ringnet::proto::opcode>, named_value<command_address> >, named_value<std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > > >' requested here
/*response*/make_converter(
^
1 error generated.
And this is almost looks like I want but Clang++ does not expand __PRETTY_FUNCTION__ in static_assert.
Is there a way to put expanded UnknownType to static_assert's message?
I also tried
static_assert(false,__PRETTY_FUNCTION__);
but it gives
error: expected string literal for diagnostic message in static_assert
#include <type_traits>
template <typename UnknownType>
struct Type_Not_Supported : std::false_type {};
template <typename UnknownType>
auto operator>>(byte_vector_view& bvv, UnknownType&&) -> byte_vector_view& {
static_assert(Type_Not_Supported<UnknownType>{});
return bvv;
}
In Clang, this yields:
prog.cc:10:5: error: static_assert failed due to requirement 'Type_Not_Supported<int>{}'
static_assert(Type_Not_Supported<UnknownType>{});
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
prog.cc:17:9: note: in instantiation of function template specialization 'operator>><int>' requested here
bvv >> 1;
^
1 error generated.
In GCC:
prog.cc: In instantiation of 'byte_vector_view& operator>>(byte_vector_view&, UnknownType&&) [with UnknownType = int]':
prog.cc:17:12: required from here
prog.cc:10:19: error: static assertion failed
10 | static_assert(Type_Not_Supported<UnknownType>{});
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
DEMO
I want to use "reshape()" fuction in Eigen unsupported tensor, but my source code cannot be compiled.
The compilation was done as follows.
g++ -std=c++14 -I (path to Eigen) eigen_practice.cpp -o eigen_practice
and here is my source code.
# include "unsupported/Eigen/CXX11/Tensor"
using namespace Eigen;
int main(){
Tensor<float, 2> input(7, 11);
Eigen::array<int, 3> three_dims{{7, 11, 1}};
Tensor<float, 3> result = input.reshape(three_dims);
return 0;
}
And here is the error messeage.
In file included from eigen_practice.cpp:12:
In file included from /Users/yamamototatsuto/Dropbox/include_for_C++/eigen/unsupported/Eigen/CXX11/Tensor:145:
/Users/yamamototatsuto/Dropbox/include_for_C++/eigen/unsupported/Eigen/CXX11/src/Tensor/Tensor.h:397:7: error:
no matching member function for call to 'resize'
resize(TensorEvaluator<const Assign, DefaultDevice>(assign, Defaul...
^~~~~~
eigen_practice.cpp:63:28: note: in instantiation of function template
specialization 'Eigen::Tensor<float, 3, 0,
long>::Tensor<Eigen::TensorReshapingOp<const std::__1::array<int, 3>,
Eigen::Tensor<float, 2, 0, long> > >' requested here
Tensor<float, 3> result = input.reshape(three_dims);
^
/Users/yamamototatsuto/Dropbox/include_for_C++/eigen/unsupported/Eigen/CXX11/src/Tensor/Tensor.h:423:10: note:
candidate function template not viable: no known conversion from 'const
Eigen::TensorEvaluator<const Eigen::TensorAssignOp<Eigen::Tensor<float, 3,
0, long>, const Eigen::TensorReshapingOp<const std::__1::array<int, 3>,
Eigen::Tensor<float, 2, 0, long> > >, Eigen::DefaultDevice>::Dimensions'
(aka 'const std::__1::array<int, 3>') to 'Eigen::Tensor<float, 3, 0,
long>::Index' (aka 'long') for 1st argument
void resize(Index firstDimension, IndexTypes... otherDimensions)
^
/Users/yamamototatsuto/Dropbox/include_for_C++/eigen/unsupported/Eigen/CXX11/src/Tensor/Tensor.h:432:28: note:
candidate function not viable: no known conversion from
'array<int, [...]>' to 'const array<long, [...]>' for 1st argument
EIGEN_DEVICE_FUNC void resize(const array<Index, NumIndices>& dimensions)
^
/Users/yamamototatsuto/Dropbox/include_for_C++/eigen/unsupported/Eigen/CXX11/src/Tensor/Tensor.h:450:28: note:
candidate function not viable: no known conversion from 'const
Eigen::TensorEvaluator<const Eigen::TensorAssignOp<Eigen::Tensor<float, 3,
0, long>, const Eigen::TensorReshapingOp<const std::__1::array<int, 3>,
Eigen::Tensor<float, 2, 0, long> > >, Eigen::DefaultDevice>::Dimensions'
(aka 'const std::__1::array<int, 3>') to 'const
DSizes<Eigen::Tensor<float, 3, 0, long>::Index, NumIndices>' (aka 'const
DSizes<long, NumIndices>') for 1st argument
EIGEN_DEVICE_FUNC void resize(const DSizes<Index, NumIndices>& dimensions) {
^
/Users/yamamototatsuto/Dropbox/include_for_C++/eigen/unsupported/Eigen/CXX11/src/Tensor/Tensor.h:479:10: note:
candidate template ignored: could not match 'Sizes' against 'array'
void resize(const Sizes<Indices...>& dimensions) {
^
/Users/yamamototatsuto/Dropbox/include_for_C++/eigen/unsupported/Eigen/CXX11/src/Tensor/Tensor.h:459:10: note:
candidate function not viable: requires 0 arguments, but 1 was provided
void resize()
^
1 error generated.
This source code is just a copy of what is in the documentation.
(https://eigen.tuxfamily.org/dox/unsupported/eigen_tensors.html)
So it should compile, but it doesn't.
How can I solve it?
And why the error message mentions about "resize()" function?
Why doesn't this work?
#include <map>
#include <memory>
void deleter(int* i) {
delete i;
}
std::map<int, std::unique_ptr<int, decltype(&deleter)>> m;
void foo(int* i) {
m[0] = std::unique_ptr<int, decltype(&deleter)>(i, &deleter);
}
Check out the incomprehensible compile error https://godbolt.org/z/Uhp9NO.
In file included from <source>:1:
In file included from /opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/map:61:
In file included from /opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/stl_map.h:63:
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/tuple:1668:9: error: no matching constructor for initialization of 'std::unique_ptr<int, void (*)(int *)>'
second(std::forward<_Args2>(std::get<_Indexes2>(__tuple2))...)
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/tuple:1655:9: note: in instantiation of function template specialization 'std::pair<const int, std::unique_ptr<int, void (*)(int *)> >::pair<int &&, 0>' requested here
: pair(__first, __second,
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/ext/new_allocator.h:136:23: note: in instantiation of function template specialization 'std::pair<const int, std::unique_ptr<int, void (*)(int *)> >::pair<int &&>' requested here
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/alloc_traits.h:475:8: note: in instantiation of function template specialization '__gnu_cxx::new_allocator<std::_Rb_tree_node<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > > >::construct<std::pair<const int, std::unique_ptr<int, void (*)(int *)> >, const std::piecewise_construct_t &, std::tuple<int &&>, std::tuple<> >' requested here
{ __a.construct(__p, std::forward<_Args>(__args)...); }
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/stl_tree.h:637:23: note: in instantiation of function template specialization 'std::allocator_traits<std::allocator<std::_Rb_tree_node<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > > > >::construct<std::pair<const int, std::unique_ptr<int, void (*)(int *)> >, const std::piecewise_construct_t &, std::tuple<int &&>, std::tuple<> >' requested here
_Alloc_traits::construct(_M_get_Node_allocator(),
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/stl_tree.h:654:4: note: in instantiation of function template specialization 'std::_Rb_tree<int, std::pair<const int, std::unique_ptr<int, void (*)(int *)> >, std::_Select1st<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > >, std::less<int>, std::allocator<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > > >::_M_construct_node<const std::piecewise_construct_t &, std::tuple<int &&>, std::tuple<> >' requested here
_M_construct_node(__tmp, std::forward<_Args>(__args)...);
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/stl_tree.h:2414:19: note: in instantiation of function template specialization 'std::_Rb_tree<int, std::pair<const int, std::unique_ptr<int, void (*)(int *)> >, std::_Select1st<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > >, std::less<int>, std::allocator<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > > >::_M_create_node<const std::piecewise_construct_t &, std::tuple<int &&>, std::tuple<> >' requested here
_Link_type __z = _M_create_node(std::forward<_Args>(__args)...);
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/stl_map.h:518:15: note: in instantiation of function template specialization 'std::_Rb_tree<int, std::pair<const int, std::unique_ptr<int, void (*)(int *)> >, std::_Select1st<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > >, std::less<int>, std::allocator<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > > >::_M_emplace_hint_unique<const std::piecewise_construct_t &, std::tuple<int &&>, std::tuple<> >' requested here
__i = _M_t._M_emplace_hint_unique(__i, std::piecewise_construct,
^
<source>:11:6: note: in instantiation of member function 'std::map<int, std::unique_ptr<int, void (*)(int *)>, std::less<int>, std::allocator<std::pair<const int, std::unique_ptr<int, void (*)(int *)> > > >::operator[]' requested here
m[0] = std::unique_ptr<int, decltype(&deleter)>(i, &deleter);
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:191:12: note: candidate template ignored: substitution failure [with _Up = void (*)(int *)]: no type named 'type' in 'std::enable_if<false, void>'
constexpr unique_ptr() noexcept
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:204:2: note: candidate constructor template not viable: requires single argument '__p', but no arguments were provided
unique_ptr(pointer __p) noexcept
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:236:12: note: candidate constructor template not viable: requires 1 argument, but 0 were provided
constexpr unique_ptr(nullptr_t) noexcept : unique_ptr() { }
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:255:2: note: candidate constructor template not viable: requires single argument '__u', but no arguments were provided
unique_ptr(unique_ptr<_Up, _Ep>&& __u) noexcept
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:265:2: note: candidate constructor template not viable: requires single argument '__u', but no arguments were provided
unique_ptr(auto_ptr<_Up>&& __u) noexcept;
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:241:7: note: candidate constructor not viable: requires single argument '__u', but no arguments were provided
unique_ptr(unique_ptr&& __u) noexcept
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:394:7: note: candidate constructor not viable: requires 1 argument, but 0 were provided
unique_ptr(const unique_ptr&) = delete;
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:215:7: note: candidate constructor not viable: requires 2 arguments, but 0 were provided
unique_ptr(pointer __p,
^
/opt/compiler-explorer/gcc-8.2.0/lib/gcc/x86_64-linux-gnu/8.2.0/../../../../include/c++/8.2.0/bits/unique_ptr.h:227:7: note: candidate constructor not viable: requires 2 arguments, but 0 were provided
unique_ptr(pointer __p,
^
1 error generated.
Compiler returned: 1
The problem is that m[0] calls the default constructor of std::unique_ptr<int, decltype(&deleter)>, which is not available because it requires the deleter pointer.
Fix:
struct Deleter {
void operator()(int* i) { delete i; }
};
std::map<int, std::unique_ptr<int, Deleter>> m;
void foo(int* i) {
m[0] = std::unique_ptr<int, Deleter>(i);
}
This is also more efficient than std::unique_ptr<int, decltype(&deleter)> because it does not have to store the very same pointer to deleter in each instance of std::unique_ptr. I.e. sizeof(std::unique_ptr<int, Deleter>) < sizeof(std::unique_ptr<int, decltype(&deleter)>).
std::unique_ptr, when using a custom deleter function like you have, is not default constructable. std::map::operator[] requires that the value type of the map be default constructable. That means as is you cannot use operator [] with this type of map.
In order for std::unique_ptr to be default constructable you need a deleter that satisfies where std::is_default_constructible<Deleter>::value is true and Deleter is not a pointer type.