I am trying to implement a fixed size multi-dimensional array whose size is determined at runtime. with the (2) overload of make_shared (template<class T> shared_ptr<T> make_shared(std::size_t N) // T is U[]). However, I am facing compilation errors (logs below). The error is not present if I change the shareds to their unique counterparts. My question is,
What is this error about?
Why unique works?
Any better way to implement such runtime-fixed multi-dimentional array container?
Minimal working example:
#include <memory>
#include <iostream>
int main() {
typedef int cell_t;
std::size_t x, y;
std::cin >> y >> x;
auto layout = std::make_shared<std::shared_ptr<cell_t[]>[]>(y);
for (std::size_t i = 0; i < y; i += 1) {
layout[i] = std::make_shared<cell_t[]>(x);
}
return 0;
}
The error message from g++-10 is as follows (note suppressed for brevity)
In file included from /usr/include/c++/10/ext/alloc_traits.h:34,
from /usr/include/c++/10/bits/stl_uninitialized.h:67,
from /usr/include/c++/10/memory:66,
from test_shared.cpp:1:
/usr/include/c++/10/bits/alloc_traits.h: In instantiation of ‘static constexpr void std::allocator_traits<std::allocator<_Up> >::construct(std::allocator_traits<std::allocator<_Up> >::allocator_type&, _Up*, _Args&& ...) [with _Up = std::shared_ptr<int []>; _Args = {long unsigned int&}; _Tp = std::shared_ptr<int []> []; std::allocator_traits<std::allocator<_Up> >::allocator_type = std::allocator<std::shared_ptr<int []> []>]’:
/usr/include/c++/10/bits/shared_ptr_base.h:551:39: required from ‘std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {long unsigned int&}; _Tp = std::shared_ptr<int []>; _Alloc = std::allocator<std::shared_ptr<int []> []>; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’
/usr/include/c++/10/bits/shared_ptr_base.h:682:16: required from ‘std::__shared_count<_Lp>::__shared_count(_Tp*&, std::_Sp_alloc_shared_tag<_Alloc>, _Args&& ...) [with _Tp = std::shared_ptr<int []>; _Alloc = std::allocator<std::shared_ptr<int []> []>; _Args = {long unsigned int&}; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’
/usr/include/c++/10/bits/shared_ptr_base.h:1371:71: required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = std::allocator<std::shared_ptr<int []> []>; _Args = {long unsigned int&}; _Tp = std::shared_ptr<int []> []; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’
/usr/include/c++/10/bits/shared_ptr.h:408:59: required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = std::allocator<std::shared_ptr<int []> []>; _Args = {long unsigned int&}; _Tp = std::shared_ptr<int []> []]’
/usr/include/c++/10/bits/shared_ptr.h:859:14: required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = std::shared_ptr<int []> []; _Alloc = std::allocator<std::shared_ptr<int []> []>; _Args = {long unsigned int&}]’
/usr/include/c++/10/bits/shared_ptr.h:875:39: required from ‘std::shared_ptr<_Tp> std::make_shared(_Args&& ...) [with _Tp = std::shared_ptr<int []> []; _Args = {long unsigned int&}]’
test_shared.cpp:7:63: required from here
/usr/include/c++/10/bits/alloc_traits.h:514:21: error: no matching function for call to ‘construct_at(std::shared_ptr<int []>*&, long unsigned int&)’
514 | std::construct_at(__p, std::forward<_Args>(__args)...);
| ~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/10/memory:65,
from test_shared.cpp:1:
/usr/include/c++/10/bits/stl_construct.h: In substitution of ‘template<class _Tp, class ... _Args> constexpr decltype (::new(void*(0)) _Tp) std::construct_at(_Tp*, _Args&& ...) [with _Tp = std::shared_ptr<int []>; _Args = {long unsigned int&}]’:
/usr/include/c++/10/bits/alloc_traits.h:514:21: required from ‘static constexpr void std::allocator_traits<std::allocator<_Up> >::construct(std::allocator_traits<std::allocator<_Up> >::allocator_type&, _Up*, _Args&& ...) [with _Up = std::shared_ptr<int []>; _Args = {long unsigned int&}; _Tp = std::shared_ptr<int []> []; std::allocator_traits<std::allocator<_Up> >::allocator_type = std::allocator<std::shared_ptr<int []> []>]’
/usr/include/c++/10/bits/shared_ptr_base.h:551:39: required from ‘std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {long unsigned int&}; _Tp = std::shared_ptr<int []>; _Alloc = std::allocator<std::shared_ptr<int []> []>; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’
/usr/include/c++/10/bits/shared_ptr_base.h:682:16: required from ‘std::__shared_count<_Lp>::__shared_count(_Tp*&, std::_Sp_alloc_shared_tag<_Alloc>, _Args&& ...) [with _Tp = std::shared_ptr<int []>; _Alloc = std::allocator<std::shared_ptr<int []> []>; _Args = {long unsigned int&}; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’
/usr/include/c++/10/bits/shared_ptr_base.h:1371:71: required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = std::allocator<std::shared_ptr<int []> []>; _Args = {long unsigned int&}; _Tp = std::shared_ptr<int []> []; __gnu_cxx::_Lock_policy _Lp = __gnu_cxx::_S_atomic]’
/usr/include/c++/10/bits/shared_ptr.h:408:59: required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_alloc_shared_tag<_Tp>, _Args&& ...) [with _Alloc = std::allocator<std::shared_ptr<int []> []>; _Args = {long unsigned int&}; _Tp = std::shared_ptr<int []> []]’
/usr/include/c++/10/bits/shared_ptr.h:859:14: required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = std::shared_ptr<int []> []; _Alloc = std::allocator<std::shared_ptr<int []> []>; _Args = {long unsigned int&}]’
/usr/include/c++/10/bits/shared_ptr.h:875:39: required from ‘std::shared_ptr<_Tp> std::make_shared(_Args&& ...) [with _Tp = std::shared_ptr<int []> []; _Args = {long unsigned int&}]’
test_shared.cpp:7:63: required from here
/usr/include/c++/10/bits/stl_construct.h:96:17: error: no matching function for call to ‘std::shared_ptr<int []>::shared_ptr(long unsigned int&)’
96 | -> decltype(::new((void*)0) _Tp(std::declval<_Args>()...))
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
g++-10 -v output:
Using built-in specs.
COLLECT_GCC=g++-10
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/10/lto-wrapper
OFFLOAD_TARGET_NAMES=nvptx-none:amdgcn-amdhsa:hsa
OFFLOAD_TARGET_DEFAULT=1
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu 10.2.0-5ubuntu1~20.04' --with-bugurl=file:///usr/share/doc/gcc-10/README.Bugs --enable-languages=c,ada,c++,go,brig,d,fortran,objc,obj-c++,m2 --prefix=/usr --with-gcc-major-version-only --program-suffix=-10 --program-prefix=x86_64-linux-gnu- --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --libdir=/usr/lib --enable-nls --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --with-default-libstdcxx-abi=new --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --enable-default-pie --with-system-zlib --enable-libphobos-checking=release --with-target-system-zlib=auto --enable-objc-gc=auto --enable-multiarch --disable-werror --with-arch-32=i686 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-offload-targets=nvptx-none=/build/gcc-10-WJNXnb/gcc-10-10.2.0/debian/tmp-nvptx/usr,amdgcn-amdhsa=/build/gcc-10-WJNXnb/gcc-10-10.2.0/debian/tmp-gcn/usr,hsa --without-cuda-driver --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
Supported LTO compression algorithms: zlib zstd
gcc version 10.2.0 (Ubuntu 10.2.0-5ubuntu1~20.04)
And from clang:
In file included from test_shared.cpp:1:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/memory:64:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/allocator.h:46:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/x86_64-linux-gnu/c++/10/bits/c++allocator.h:33:
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/ext/new_allocator.h:150:23: error: no matching constructor for initialization of 'std::shared_ptr<int []>'
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/alloc_traits.h:512:8: note: in instantiation of function template specialization '__gnu_cxx::new_allocator<std::shared_ptr<int []> []>::construct<std::shared_ptr<int []>, unsigned long &>' requested here
__a.construct(__p, std::forward<_Args>(__args)...);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr_base.h:551:30: note: in instantiation of function template specialization 'std::allocator_traits<std::allocator<std::shared_ptr<int []> []> >::construct<std::shared_ptr<int []>, unsigned long &>' requested here
allocator_traits<_Alloc>::construct(__a, _M_ptr(),
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr_base.h:683:6: note: in instantiation of function template specialization 'std::_Sp_counted_ptr_inplace<std::shared_ptr<int []>, std::allocator<std::shared_ptr<int []> []>, __gnu_cxx::_S_atomic>::_Sp_counted_ptr_inplace<unsigned long &>' requested here
_Sp_cp_type(__a._M_a, std::forward<_Args>(__args)...);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr_base.h:1371:14: note: in instantiation of function template specialization 'std::__shared_count<__gnu_cxx::_S_atomic>::__shared_count<std::shared_ptr<int []>, std::allocator<std::shared_ptr<int []> []>, unsigned long &>' requested here
: _M_ptr(), _M_refcount(_M_ptr, __tag, std::forward<_Args>(__args)...)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:408:4: note: in instantiation of function template specialization 'std::__shared_ptr<std::shared_ptr<int []> [], __gnu_cxx::_S_atomic>::__shared_ptr<std::allocator<std::shared_ptr<int []> []>, unsigned long &>' requested here
: __shared_ptr<_Tp>(__tag, std::forward<_Args>(__args)...)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:859:14: note: in instantiation of function template specialization 'std::shared_ptr<std::shared_ptr<int []> []>::shared_ptr<std::allocator<std::shared_ptr<int []> []>, unsigned long &>' requested here
return shared_ptr<_Tp>(_Sp_alloc_shared_tag<_Alloc>{__a},
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:875:19: note: in instantiation of function template specialization 'std::allocate_shared<std::shared_ptr<int []> [], std::allocator<std::shared_ptr<int []> []>, unsigned long &>' requested here
return std::allocate_shared<_Tp>(std::allocator<_Tp_nc>(),
^
test_shared.cpp:7:21: note: in instantiation of function template specialization 'std::make_shared<std::shared_ptr<int []> [], unsigned long &>' requested here
auto layout = std::make_shared<std::shared_ptr<cell_t[]>[]>(y);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:149:7: note: candidate constructor not viable: no known conversion from 'unsigned long' to 'const std::shared_ptr<int []>' for 1st argument
shared_ptr(const shared_ptr&) noexcept = default; ///< Copy constructor
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:303:7: note: candidate constructor not viable: no known conversion from 'unsigned long' to 'std::shared_ptr<int []>' for 1st argument
shared_ptr(shared_ptr&& __r) noexcept
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:356:17: note: candidate constructor not viable: no known conversion from 'unsigned long' to 'std::nullptr_t' (aka 'nullptr_t') for 1st argument
constexpr shared_ptr(nullptr_t) noexcept : shared_ptr() { }
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:159:2: note: candidate template ignored: could not match '_Yp *' against 'unsigned long'
shared_ptr(_Yp* __p) : __shared_ptr<_Tp>(__p) { }
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:295:2: note: candidate template ignored: could not match 'shared_ptr<type-parameter-0-0>' against 'unsigned long'
shared_ptr(const shared_ptr<_Yp>& __r) noexcept
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:312:2: note: candidate template ignored: could not match 'shared_ptr<type-parameter-0-0>' against 'unsigned long'
shared_ptr(shared_ptr<_Yp>&& __r) noexcept
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:324:11: note: candidate template ignored: could not match 'weak_ptr<type-parameter-0-0>' against 'unsigned long'
explicit shared_ptr(const weak_ptr<_Yp>& __r)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:331:2: note: candidate template ignored: could not match 'auto_ptr<type-parameter-0-0>' against 'unsigned long'
shared_ptr(auto_ptr<_Yp>&& __r);
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:339:2: note: candidate template ignored: could not match 'unique_ptr<type-parameter-0-0, type-parameter-0-1>' against 'unsigned long'
shared_ptr(unique_ptr<_Yp, _Del>&& __r)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:348:2: note: candidate template ignored: could not match 'unique_ptr<type-parameter-0-0, type-parameter-0-1>' against 'unsigned long'
shared_ptr(unique_ptr<_Yp, _Del>&& __r)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:407:2: note: candidate template ignored: could not match '_Sp_alloc_shared_tag<type-parameter-0-0>' against 'unsigned long'
shared_ptr(_Sp_alloc_shared_tag<_Alloc> __tag, _Args&&... __args)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:147:17: note: candidate constructor not viable: requires 0 arguments, but 1 was provided
constexpr shared_ptr() noexcept : __shared_ptr<_Tp>() { }
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:176:2: note: candidate constructor template not viable: requires 2 arguments, but 1 was provided
shared_ptr(_Yp* __p, _Deleter __d)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:193:2: note: candidate constructor template not viable: requires 2 arguments, but 1 was provided
shared_ptr(nullptr_t __p, _Deleter __d)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:256:2: note: candidate constructor template not viable: requires 2 arguments, but 1 was provided
shared_ptr(const shared_ptr<_Yp>& __r, element_type* __p) noexcept
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:416:7: note: candidate constructor not viable: requires 2 arguments, but 1 was provided
shared_ptr(const weak_ptr<_Tp>& __r, std::nothrow_t)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:213:2: note: candidate constructor template not viable: requires 3 arguments, but 1 was provided
shared_ptr(_Yp* __p, _Deleter __d, _Alloc __a)
^
/usr/bin/../lib/gcc/x86_64-linux-gnu/10/../../../../include/c++/10/bits/shared_ptr.h:232:2: note: candidate constructor template not viable: requires 3 arguments, but 1 was provided
shared_ptr(nullptr_t __p, _Deleter __d, _Alloc __a)
^
1 error generated.
clang -v output:
clang version 10.0.0-4ubuntu1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/10
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/9
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/10
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/8
Found candidate GCC installation: /usr/lib/gcc/x86_64-linux-gnu/9
Selected GCC installation: /usr/bin/../lib/gcc/x86_64-linux-gnu/10
Candidate multilib: .;#m64
Selected multilib: .;#m64
Original code, if it helps,
class gridmap {
private:
std::shared_ptr<std::shared_ptr<cell_t[]>[]> layout;
std::size_t w;
std::size_t h;
public:
gridmap(std::size_t y, std::size_t x) {
layout = std::make_shared<std::shared_ptr<cell_t[]>[]>(y);
for (std::size_t i = 0; i < y; i += 1) {
layout[i] = std::make_shared<cell_t[]>(x);
}
h = y;
w = x;
}
std::shared_ptr<cell_t[]>& operator[](size_t r) {
return layout[r];
}
};
For your first question "What is this error about?":
GCC libstdc++ and Clang libc++ has no support for "Extending std::make_shared() to support arrays " which introduced in c++20 yet. So these compilers will try to use template< class T, class... Args > shared_ptr<T> make_shared( Args&&... args );, which trying to forward your arguments (in this case, a cell_t = std::size_t) to construct a std::shared_ptr<cell_t[]>[]. It cannot be done, so they complain about it.
You can check compiler compatibility here: Compiler support for C++20
Related
I have a strange compilation problem that I can't understand.
//I know, you should never derive from the STL Library
template<class T>
class SharedClass : private shared_ptr<T>
{
public:
template<class T2>
SharedClass(T2&& t2) :
shared_ptr<T>(make_shared<T>(move(t2)))
{}
virtual ~SharedClass()
{}
};
class A
{
public:
typedef function<void(SharedClass<A>)> Callback;
A(Callback callback)
{ }
};
main.cpp
SharedClass<A> shared([](SharedClass<A>){ });
Compile Log:
In file included from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33:0,
from /usr/include/c++/7/bits/allocator.h:46,
from /usr/include/c++/7/string:41,
from /usr/include/c++/7/bits/locale_classes.h:40,
from /usr/include/c++/7/bits/ios_base.h:41,
from /usr/include/c++/7/ios:42,
from /usr/include/c++/7/ostream:38,
from /usr/include/c++/7/iostream:39,
from main.cpp:9:
/usr/include/c++/7/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = A; _Args = {SharedClass<A>}; _Tp = A]’:
/usr/include/c++/7/bits/alloc_traits.h:475:4: required from ‘static void std::allocator_traits<std::allocator<_CharT>>::construct(std::allocator_traits<std::allocator<_CharT> >::allocator_type&, _Up*, _Args&& ...) [with _Up = A; _Args = {SharedClass<A>}; _Tp = A; std::allocator_traits<std::allocator<_CharT>>::allocator_type = std::allocator<A>]’
/usr/include/c++/7/bits/shared_ptr_base.h:526:39: required from ‘std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {SharedClass<A>}; _Tp = A; _Alloc = std::allocator<A>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’ /usr/include/c++/7
/bits/shared_ptr_base.h:637:4: required from ‘std::__shared_count<_Lp>::__shared_count(std::_Sp_make_shared_tag, _Tp*, const _Alloc&, _Args&& ...) [with _Tp = A; _Alloc = std::allocator<A>; _Args = {SharedClass<A>}; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr_base.h:1295:35: required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<A>; _Args = {SharedClass<A>}; _Tp = A; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr.h:344:64: required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<A>; _Args = {SharedClass<A>}; _Tp = A]’
/usr/include/c++/7/bits/shared_ptr.h:690:14: [ skipping 9 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/c++/7/bits/shared_ptr_base.h:1295:35: required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<A>; _Args = {main()::<lambda(SharedClass<A>)>}; _Tp = A; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr.h:344:64: required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<A>; _Args = {main()::<lambda(SharedClass<A>)>}; _Tp = A]’ /usr/include/c++/7/bits/shared_ptr.h:690:14: required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = A; _Alloc = std::allocator<A>; _Args = {main()::<lambda(SharedClass<A>)>}]’
/usr/include/c++/7/bits/shared_ptr.h:706:39: required from ‘std::shared_ptr<_Tp> std::make_shared(_Args&& ...) [with _Tp = A; _Args = {main()::<lambda(SharedClass<A>)>}]’
main.cpp:21:33: required from ‘SharedClass<T>::SharedClass(T2&&) [with T2 = main()::<lambda(SharedClass<A>)>; T = A]’
main.cpp:39:48: required from here
/usr/include/c++/7/ext/new_allocator.h:136:4: error: no matching function for call to ‘A::A(SharedClass)’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
main.cpp:33:5: note: candidate: A::A(A::Callback)
A(Callback callback)
^ main.cpp:33:5: note: no known conversion for argument 1 from ‘SharedClass’ to ‘A::Callback {aka std::function)>}’
main.cpp:28:7: note: candidate: constexpr A::A(const A&)
class A
^ main.cpp:28:7: note: no known conversion for argument 1 from ‘SharedClass’ to ‘const A&’
main.cpp:28:7: note: candidate: constexpr A::A(A&&)
main.cpp:28:7: note: no known conversion for argument 1 from ‘SharedClass’ to ‘A&&’
If I change the constructor of the SharedClass class like this SharedClass (T2 t2) it compiles.
As your lambda takes its parameters by value it needs to be able to create copies of those parameters, it does this by calling the move constructor. As you have defined a templated constructor with the same signature as the move constructor the compiler attempts to use it as a move constructor. Adding default copy (for completeness) and move constructors fixes the issue:
SharedClass(const SharedClass&) = default;
SharedClass(SharedClass&&) = default;
Your existing constructor doesn't work as a move constructor because there is no constructor for A which takes a SharedClass<A> parameter so make_shared<A> doesn't compile when passed a SharedClass<A> parameter.
I'm getting the following errors when trying compile my HuffmanNode class for an assignment, it seems to be something to do with the shared_ptrs in the class, but I have no idea as to what is actually going wrong because of the sheer amount of text that I can't seem to find the actual problem.
g++ -std=c++11 -c src/HuffmanNode.cpp -o obj/HuffmanNode.o -I headers
In file included from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33:0,
from /usr/include/c++/7/bits/allocator.h:46,
from /usr/include/c++/7/memory:63,
from headers/HuffmanNode.hpp:9,
from src/HuffmanNode.cpp:5:
/usr/include/c++/7/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = FLNRHE001::HuffmanNode; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode]’:
/usr/include/c++/7/bits/alloc_traits.h:475:4: required from ‘static void std::allocator_traits<std::allocator<_Tp1> >::construct(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&, _Up*, _Args&& ...) [with _Up = FLNRHE001::HuffmanNode; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<FLNRHE001::HuffmanNode>]’
/usr/include/c++/7/bits/shared_ptr_base.h:526:39: required from ‘std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr_base.h:637:4: required from ‘std::__shared_count<_Lp>::__shared_count(std::_Sp_make_shared_tag, _Tp*, const _Alloc&, _Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr_base.h:1295:35: required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr.h:344:64: required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode]’
/usr/include/c++/7/bits/shared_ptr.h:690:14: required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}]’
/usr/include/c++/7/bits/shared_ptr.h:706:39: required from ‘std::shared_ptr<_Tp> std::make_shared(_Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Args = {const std::shared_ptr<FLNRHE001::HuffmanNode>&}]’
src/HuffmanNode.cpp:34:72: required from here
/usr/include/c++/7/ext/new_allocator.h:136:4: error: no matching function for call to ‘FLNRHE001::HuffmanNode::HuffmanNode(const std::shared_ptr<FLNRHE001::HuffmanNode>&)’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/HuffmanNode.cpp:41:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(FLNRHE001::HuffmanNode&&)
HuffmanNode::HuffmanNode(HuffmanNode &&n)
^~~~~~~~~~~
src/HuffmanNode.cpp:41:1: note: no known conversion for argument 1 from ‘const std::shared_ptr<FLNRHE001::HuffmanNode>’ to ‘FLNRHE001::HuffmanNode&&’
src/HuffmanNode.cpp:33:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(const FLNRHE001::HuffmanNode&)
HuffmanNode::HuffmanNode(const HuffmanNode &n)
^~~~~~~~~~~
src/HuffmanNode.cpp:33:1: note: no known conversion for argument 1 from ‘const std::shared_ptr<FLNRHE001::HuffmanNode>’ to ‘const FLNRHE001::HuffmanNode&’
src/HuffmanNode.cpp:11:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(char, int, std::shared_ptr<FLNRHE001::HuffmanNode>, std::shared_ptr<FLNRHE001::HuffmanNode>)
HuffmanNode::HuffmanNode(char c, int f, std::shared_ptr<HuffmanNode> l, std::shared_ptr<HuffmanNode> r)
^~~~~~~~~~~
src/HuffmanNode.cpp:11:1: note: candidate expects 4 arguments, 1 provided
In file included from /usr/include/x86_64-linux-gnu/c++/7/bits/c++allocator.h:33:0,
from /usr/include/c++/7/bits/allocator.h:46,
from /usr/include/c++/7/memory:63,
from headers/HuffmanNode.hpp:9,
from src/HuffmanNode.cpp:5:
/usr/include/c++/7/ext/new_allocator.h: In instantiation of ‘void __gnu_cxx::new_allocator<_Tp>::construct(_Up*, _Args&& ...) [with _Up = FLNRHE001::HuffmanNode; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp
= FLNRHE001::HuffmanNode]’:
/usr/include/c++/7/bits/alloc_traits.h:475:4: required from ‘static void std::allocator_traits<std::allocator<_Tp1> >::construct(std::allocator_traits<std::allocator<_Tp1> >::allocator_type&, _Up*, _Args&& ...) [with _Up = FLNRHE001::HuffmanNode; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode; std::allocator_traits<std::allocator<_Tp1> >::allocator_type = std::allocator<FLNRHE001::HuffmanNode>]’
/usr/include/c++/7/bits/shared_ptr_base.h:526:39: required from ‘std::_Sp_counted_ptr_inplace<_Tp, _Alloc, _Lp>::_Sp_counted_ptr_inplace(_Alloc, _Args&& ...) [with _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&};
_Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr_base.h:637:4: required from ‘std::__shared_count<_Lp>::__shared_count(std::_Sp_make_shared_tag, _Tp*, const _Alloc&, _Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr_base.h:1295:35: required from ‘std::__shared_ptr<_Tp, _Lp>::__shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode; __gnu_cxx::_Lock_policy _Lp = (__gnu_cxx::_Lock_policy)2]’
/usr/include/c++/7/bits/shared_ptr.h:344:64: required from ‘std::shared_ptr<_Tp>::shared_ptr(std::_Sp_make_shared_tag, const _Alloc&, _Args&& ...) [with _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}; _Tp = FLNRHE001::HuffmanNode]’
/usr/include/c++/7/bits/shared_ptr.h:690:14: required from ‘std::shared_ptr<_Tp> std::allocate_shared(const _Alloc&, _Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Alloc = std::allocator<FLNRHE001::HuffmanNode>; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}]’
/usr/include/c++/7/bits/shared_ptr.h:706:39: required from ‘std::shared_ptr<_Tp> std::make_shared(_Args&& ...) [with _Tp = FLNRHE001::HuffmanNode; _Args = {std::shared_ptr<FLNRHE001::HuffmanNode>&}]’
src/HuffmanNode.cpp:93:52: required from here
/usr/include/c++/7/ext/new_allocator.h:136:4: error: no matching function for call to ‘FLNRHE001::HuffmanNode::HuffmanNode(std::shared_ptr<FLNRHE001::HuffmanNode>&)’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/HuffmanNode.cpp:41:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(FLNRHE001::HuffmanNode&&)
HuffmanNode::HuffmanNode(HuffmanNode &&n)
^~~~~~~~~~~
src/HuffmanNode.cpp:41:1: note: no known conversion for argument 1 from ‘std::shared_ptr<FLNRHE001::HuffmanNode>’ to ‘FLNRHE001::HuffmanNode&&’
src/HuffmanNode.cpp:33:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(const FLNRHE001::HuffmanNode&)
HuffmanNode::HuffmanNode(const HuffmanNode &n)
^~~~~~~~~~~
src/HuffmanNode.cpp:33:1: note: no known conversion for argument 1 from ‘std::shared_ptr<FLNRHE001::HuffmanNode>’ to ‘const FLNRHE001::HuffmanNode&’
src/HuffmanNode.cpp:11:1: note: candidate: FLNRHE001::HuffmanNode::HuffmanNode(char, int, std::shared_ptr<FLNRHE001::HuffmanNode>, std::shared_ptr<FLNRHE001::HuffmanNode>)
HuffmanNode::HuffmanNode(char c, int f, std::shared_ptr<HuffmanNode> l, std::shared_ptr<HuffmanNode> r)
^~~~~~~~~~~
src/HuffmanNode.cpp:11:1: note: candidate expects 4 arguments, 1 provided
I've tried looking up the errors but can't seem to find anything that solves the problem.
I can't post my entire code due to it being an assignment, but the lines that are mentioned in the error text are my constructor declarations, and as stated above, the problem seems to lie in the shared_ptrs:
line 11: HuffmanNode::HuffmanNode(char c, int f, std::shared_ptr<HuffmanNode> l, std::shared_ptr<HuffmanNode> r)
line 33: HuffmanNode::HuffmanNode(const HuffmanNode &n) : ch(n.ch), freq(n.freq), left(std::make_shared<HuffmanNode>(n.left)), right(std::make_shared<HuffmanNode>(n.right))
line 41: HuffmanNode::HuffmanNode(HuffmanNode &&n) : ch(std::move(n.ch)), freq(std::move(n.freq)), left(std::move(n.left)), right(std::move(n.right))
EDIT:
Here's what I can post according to the school regulations, the only method that has any content inside it of the problem areas is the move constructor, and that is just ensuring that there will be no double deletion errors when the destructor is called. This gives me the same errors as above does.
#include <memory>
class HuffmanNode
{
char ch;
int freq;
std::shared_ptr<HuffmanNode> left, right;
// Node constructor for leaf node
HuffmanNode(char c, int f, std::shared_ptr<HuffmanNode> l, std::shared_ptr<HuffmanNode> r)
: ch(c), freq(f), left(l), right(r)
{
// Handled in initialiser list
}
HuffmanNode(const HuffmanNode &n)
: ch(n.ch), freq(n.freq), left(std::make_shared<HuffmanNode>(n.left)),
right(std::make_shared<HuffmanNode>(n.right))
{
// Handled by initialiser list
}
// Move Constructor
HuffmanNode(HuffmanNode &&n)
: ch(std::move(n.ch)), freq(std::move(n.freq)),
left(std::move(n.left)),
right(std::move(n.right))
{
}
};
The errors were arising from attempting to use make_shared to create a copy of the left and right pointers, in this case I only require a shallow copy as is made by the shared_ptr copy constructor.
The corrected solution was only a change to the move constructor as follows-:
HuffmanNode(const HuffmanNode &n)
: ch(n.ch), freq(n.freq), left(n.left),
right(n.right)
{
// Handled by initialiser list
}
Thanks to Sam Varshavchik for the help in this!
The following line of code which is a part of file is producing error
.\Graph.h:16:3: note: candidate: node::node(int)
node(int n) : element(n){
^~~~
.\Graph.h:16:3: note: candidate expects 1 argument, 0 provided
.\Graph.h:10:8: note: candidate: constexpr node::node(const node&)
struct node{
^~~~
.\Graph.h:10:8: note: candidate expects 1 argument, 0 provided
.\Graph.h:10:8: note: candidate: constexpr node::node(node&&)
.\Graph.h:10:8: note: candidate expects 1 argument, 0 provided
The above error typically occurs due to the absence of default constructor as I have researched.
struct node{
int element;
static vector<bool> check;
static vector<int> dist;
static vector<int> f;
static vector<node> leader;
node(int n) : element(n){
if(check.size()<n+1){
check.resize(n+1);
leader.resize(n+1);
}
}
bool operator < (node& n){
if(this->element<n.element)
return 1;
else
return 0;
}
};
However, default constructor is not used anywhere else. Also, when I comment out static vector<node> leader and other operations related to it, the program doesnt give any error.
So, is the problem because I have declared a container of same type in the same class ?
EDIT - included full error message
In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\vector:62:0,
from .\Graph.h:5:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_construct.h: In instantiation of 'void std::_Construct(_T1*, _Args&& ...) [with _T1 = node; _Args = {}]':
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_uninitialized.h:519:18: required from 'static _ForwardIterator std::__uninitialized_default_n_1<_TrivialValueType>::__uninit_default_n(_ForwardIterator, _Size) [with _ForwardIterator = node*; _Size = unsigned int; bool _TrivialValueType = false]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_uninitialized.h:575:20: required from '_ForwardIterator std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator = node*; _Size = unsigned int]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_uninitialized.h:637:44: required from '_ForwardIterator std::__uninitialized_default_n_a(_ForwardIterator, _Size, std::allocator<_Tp>&) [with _ForwardIterator = node*; _Size = unsigned int; _Tp = node]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\vector.tcc:549:35: required from 'void std::vector<_Tp, _Alloc>::_M_default_append(std::vector<_Tp, _Alloc>::size_type) [with _Tp = node; _Alloc = std::allocator<node>; std::vector<_Tp, _Alloc>::size_type = unsigned int]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_vector.h:677:21: required from 'void std::vector<_Tp, _Alloc>::resize(std::vector<_Tp, _Alloc>::size_type) [with _Tp = node; _Alloc = std::allocator<node>; std::vector<_Tp, _Alloc>::size_type = unsigned int]'
.\Graph.h:19:24: required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_construct.h:75:7: error: no matching function for call to 'node::node()'
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\Graph.h:16:3: note: candidate: node::node(int)
node(int n) : element(n){
^~~~
.\Graph.h:16:3: note: candidate expects 1 argument, 0 provided
.\Graph.h:10:8: note: candidate: constexpr node::node(const node&)
struct node{
^~~~
.\Graph.h:10:8: note: candidate expects 1 argument, 0 provided
.\Graph.h:10:8: note: candidate: constexpr node::node(node&&)
.\Graph.h:10:8: note: candidate expects 1 argument, 0 provided
In file included from c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\vector:62:0,
from .\Graph.h:5:
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_construct.h: In instantiation of 'void std::_Construct(_T1*, _Args&& ...) [with _T1 = node; _Args = {}]':
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_uninitialized.h:519:18: required from 'static _ForwardIterator std::__uninitialized_default_n_1<_TrivialValueType>::__uninit_default_n(_ForwardIterator, _Size) [with _ForwardIterator = node*; _Size = unsigned int; bool _TrivialValueType = false]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_uninitialized.h:575:20: required from '_ForwardIterator std::__uninitialized_default_n(_ForwardIterator, _Size) [with _ForwardIterator = node*; _Size = unsigned int]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_uninitialized.h:637:44: required from '_ForwardIterator std::__uninitialized_default_n_a(_ForwardIterator, _Size, std::allocator<_Tp>&) [with _ForwardIterator = node*; _Size = unsigned int; _Tp = node]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\vector.tcc:549:35: required from 'void std::vector<_Tp, _Alloc>::_M_default_append(std::vector<_Tp, _Alloc>::size_type) [with _Tp = node; _Alloc = std::allocator<node>; std::vector<_Tp, _Alloc>::size_type = unsigned int]'
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_vector.h:677:21: required from 'void std::vector<_Tp, _Alloc>::resize(std::vector<_Tp, _Alloc>::size_type) [with _Tp = node; _Alloc = std::allocator<node>; std::vector<_Tp, _Alloc>::size_type = unsigned int]'
.\Graph.h:19:24: required from here
c:\mingw\lib\gcc\mingw32\6.3.0\include\c++\bits\stl_construct.h:75:7: error: no matching function for call to 'node::node()'
{ ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
.\Graph.h:16:3: note: candidate: node::node(int)
node(int n) : element(n){
^~~~
.\Graph.h:16:3: note: candidate expects 1 argument, 0 provided
.\Graph.h:10:8: note: candidate: constexpr node::node(const node&)
struct node{
^~~~
.\Graph.h:10:8: note: candidate expects 1 argument, 0 provided
.\Graph.h:10:8: note: candidate: constexpr node::node(node&&)
.\Graph.h:10:8: note: candidate expects 1 argument, 0 provided
leader.resize(n+1); will resize the vector to have n+1 default constructed nodes. And so you need a default constructor if you want to have this line.
However without more information with what you expect this vector to be or what to do with it its hard to know how you should fix it.
Note: You can add a default constructor by adding node() = default; to your node class.
class taskq {
public:
int trigger(taskq &tq);
mutex mtx;
};
void func_wrapper(taskq &tq) {
cout<<endl;
}
int taskq::trigger(taskq &tq) {
thread thread(func_wrapper, tq);
return 0;
}
I tried to compile the above simple code but I am keep getting errors because of line thread thread(func_wrapper, tq);.
What's wrong with this code?
How could I fix it?
The error message is as below:
In file included from /usr/include/c++/4.9/thread:39:0,
from taskq.C:2:
/usr/include/c++/4.9/functional: In instantiation of ‘struct std::_Bind_simple<void (*(taskq))(taskq&)>’:
/usr/include/c++/4.9/thread:140:47: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(taskq&); _Args = {taskq&}]’
taskq.C:20:33: required from here
/usr/include/c++/4.9/functional:1665:61: error: no type named ‘type’ in ‘class std::result_of<void (*(taskq))(taskq&)>’
typedef typename result_of<_Callable(_Args...)>::type result_type;
^
/usr/include/c++/4.9/functional:1695:9: error: no type named ‘type’ in ‘class std::result_of<void (*(taskq))(taskq&)>’
_M_invoke(_Index_tuple<_Indices...>)
^
In file included from /usr/include/c++/4.9/functional:55:0,
from /usr/include/c++/4.9/thread:39,
from taskq.C:2:
/usr/include/c++/4.9/tuple: In instantiation of ‘constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(_UHead&&) [with _UHead = taskq; <template-parameter-2-2> = void; long unsigned int _Idx = 1ul; _Head = taskq]’:
/usr/include/c++/4.9/tuple:271:42: required from ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(std::_Tuple_impl<_Idx, _Head, _Tail ...>&&) [with long unsigned int _Idx = 1ul; _Head = taskq; _Tail = {}]’
/usr/include/c++/4.9/type_traits:900:43: required by substitution of ‘template<class _Tp, class _Arg, class> static std::true_type std::__do_is_direct_constructible_impl::__test(int) [with _Tp = std::_Tuple_impl<1ul, taskq>; _Arg = std::_Tuple_impl<1ul, taskq>&&; <template-parameter-1-3> = <missing>]’
/usr/include/c++/4.9/type_traits:912:43: required from ‘struct std::__is_direct_constructible_impl<std::_Tuple_impl<1ul, taskq>, std::_Tuple_impl<1ul, taskq>&&>’
/usr/include/c++/4.9/type_traits:134:12: required from ‘struct std::__and_<std::is_destructible<std::_Tuple_impl<1ul, taskq> >, std::__is_direct_constructible_impl<std::_Tuple_impl<1ul, taskq>, std::_Tuple_impl<1ul, taskq>&&> >’
/usr/include/c++/4.9/type_traits:916:12: required from ‘struct std::__is_direct_constructible_new_safe<std::_Tuple_impl<1ul, taskq>, std::_Tuple_impl<1ul, taskq>&&>’
/usr/include/c++/4.9/type_traits:994:12: [ skipping 7 instantiation contexts, use -ftemplate-backtrace-limit=0 to disable ]
/usr/include/c++/4.9/type_traits:1175:12: required from ‘struct std::is_nothrow_move_constructible<std::_Tuple_impl<1ul, taskq> >’
/usr/include/c++/4.9/type_traits:134:12: required from ‘struct std::__and_<std::is_nothrow_move_constructible<void (*)(taskq&)>, std::is_nothrow_move_constructible<std::_Tuple_impl<1ul, taskq> > >’
/usr/include/c++/4.9/tuple:267:7: required from ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(std::_Tuple_impl<_Idx, _Head, _Tail ...>&&) [with long unsigned int _Idx = 0ul; _Head = void (*)(taskq&); _Tail = {taskq}]’
/usr/include/c++/4.9/functional:1727:41: required from ‘typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type std::__bind_simple(_Callable&&, _Args&& ...) [with _Callable = void (&)(taskq&); _Args = {taskq&}; typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type = std::_Bind_simple<void (*(taskq))(taskq&)>]’
/usr/include/c++/4.9/thread:140:47: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(taskq&); _Args = {taskq&}]’
taskq.C:20:33: required from here
/usr/include/c++/4.9/tuple:140:42: error: use of deleted function ‘taskq::taskq(taskq&&)’
: _M_head_impl(std::forward<_UHead>(__h)) { }
^
taskq.C:9:7: note: ‘taskq::taskq(taskq&&)’ is implicitly deleted because the default definition would be ill-formed:
class taskq {
^
taskq.C:9:7: error: use of deleted function ‘std::mutex::mutex(const std::mutex&)’
In file included from taskq.C:3:0:
/usr/include/c++/4.9/mutex:129:5: note: declared here
mutex(const mutex&) = delete;
^
In file included from /usr/include/c++/4.9/functional:55:0,
from /usr/include/c++/4.9/thread:39,
from taskq.C:2:
/usr/include/c++/4.9/tuple: In instantiation of ‘constexpr std::_Head_base<_Idx, _Head, false>::_Head_base(const _Head&) [with long unsigned int _Idx = 1ul; _Head = taskq]’:
/usr/include/c++/4.9/tuple:255:44: recursively required from ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const _Head&, const _Tail& ...) [with long unsigned int _Idx = 1ul; _Head = taskq; _Tail = {}]’
/usr/include/c++/4.9/tuple:255:44: required from ‘constexpr std::_Tuple_impl<_Idx, _Head, _Tail ...>::_Tuple_impl(const _Head&, const _Tail& ...) [with long unsigned int _Idx = 0ul; _Head = void (*)(taskq&); _Tail = {taskq}]’
/usr/include/c++/4.9/tuple:531:30: required from ‘constexpr std::tuple<_T1, _T2>::tuple(const _T1&, const _T2&) [with _T1 = void (*)(taskq&); _T2 = taskq]’
/usr/include/c++/4.9/functional:1678:74: required from ‘std::_Bind_simple<_Callable(_Args ...)>::_Bind_simple(_Callable&&, _Args2&& ...) [with _Args2 = {taskq&}; <template-parameter-2-2> = void; _Callable = void (*)(taskq&); _Args = {taskq}]’
/usr/include/c++/4.9/functional:1727:41: required from ‘typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type std::__bind_simple(_Callable&&, _Args&& ...) [with _Callable = void (&)(taskq&); _Args = {taskq&}; typename std::_Bind_simple_helper<_Func, _BoundArgs>::__type = std::_Bind_simple<void (*(taskq))(taskq&)>]’
/usr/include/c++/4.9/thread:140:47: required from ‘std::thread::thread(_Callable&&, _Args&& ...) [with _Callable = void (&)(taskq&); _Args = {taskq&}]’
taskq.C:20:33: required from here
/usr/include/c++/4.9/tuple:134:25: error: use of deleted function ‘taskq::taskq(const taskq&)’
: _M_head_impl(__h) { }
^
taskq.C:9:7: note: ‘taskq::taskq(const taskq&)’ is implicitly deleted because the default definition would be ill-formed:
class taskq {
^
taskq.C:9:7: error: use of deleted function ‘std::mutex::mutex(const std::mutex&)’
In file included from taskq.C:3:0:
/usr/include/c++/4.9/mutex:129:5: note: declared here
mutex(const mutex&) = delete;
^
make: *** [taskq.o] Error 1
thread thread(func_wrapper, std::ref(tq));
Note that you need to make sure the reference is still valid while you are executing func_wrapper (since I'm guessing such function uses tq).
std::thread thread([&tq]() {
func_wrapper(tq);
});
I'm having trouble with unique_ptr and a deleter. The following won't compile:
unique_ptr<RSA> rsa(RSA_new(), ::RSA_free);
unique_ptr<RSA> rsa(RSA_new(), ptr_fun(RSA_free));
The compile errors are shown below.
shared_ptr worked fine, but I need to release one of those pointers when assigning it into another structure (and shared_ptr is not amicable).
I'm using GCC 4.7 on Debian 7.3 (x64). Everything is fully patched.
Any ideas what I am doing wrong?
../source/ac-pki.cpp:461:46: error: no matching function for call to ‘std::unique_ptr<rsa_st>::unique_ptr(RSA*, void (&)(RSA*))’
../source/ac-pki.cpp:461:46: note: candidates are:
In file included from /usr/include/c++/4.7/memory:86:0,
from /home/jwalton/test/include/ac-common.h:39,
from ../source/ac-pki.cpp:1:
/usr/include/c++/4.7/bits/unique_ptr.h:164:2: note: template<class _Up, class> std::unique_ptr::unique_ptr(std::auto_ptr<_Up>&&)
/usr/include/c++/4.7/bits/unique_ptr.h:164:2: note: template argument deduction/substitution failed:
../source/ac-pki.cpp:461:46: note: mismatched types ‘std::auto_ptr<_Up>’ and ‘RSA* {aka rsa_st*}’
In file included from /usr/include/c++/4.7/memory:86:0,
from /home/jwalton/test/include/ac-common.h:39,
from ../source/ac-pki.cpp:1:
/usr/include/c++/4.7/bits/unique_ptr.h:155:2: note: template<class _Up, class _Ep, class> std::unique_ptr::unique_ptr(std::unique_ptr<_Up, _Ep>&&)
/usr/include/c++/4.7/bits/unique_ptr.h:155:2: note: template argument deduction/substitution failed:
../source/ac-pki.cpp:461:46: note: mismatched types ‘std::unique_ptr<_Up, _Ep>’ and ‘RSA* {aka rsa_st*}’
In file included from /usr/include/c++/4.7/memory:86:0,
from /home/jwalton/test/include/ac-common.h:39,
from ../source/ac-pki.cpp:1:
/usr/include/c++/4.7/bits/unique_ptr.h:142:7: note: std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>&&) [with _Tp = rsa_st; _Dp = std::default_delete<rsa_st>; std::unique_ptr<_Tp, _Dp> = std::unique_ptr<rsa_st>]
/usr/include/c++/4.7/bits/unique_ptr.h:142:7: note: candidate expects 1 argument, 2 provided
/usr/include/c++/4.7/bits/unique_ptr.h:136:17: note: constexpr std::unique_ptr<_Tp, _Dp>::unique_ptr(std::nullptr_t) [with _Tp = rsa_st; _Dp = std::default_delete<rsa_st>; std::nullptr_t = std::nullptr_t]
/usr/include/c++/4.7/bits/unique_ptr.h:136:17: note: candidate expects 1 argument, 2 provided
/usr/include/c++/4.7/bits/unique_ptr.h:130:7: note: std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>::pointer, typename std::remove_reference<_To>::type&&) [with _Tp = rsa_st; _Dp = std::default_delete<rsa_st>; std::unique_ptr<_Tp, _Dp>::pointer = rsa_st*; typename std::remove_reference<_To>::type = std::default_delete<rsa_st>]
/usr/include/c++/4.7/bits/unique_ptr.h:130:7: note: no known conversion for argument 2 from ‘void(RSA*) {aka void(rsa_st*)}’ to ‘std::remove_reference<std::default_delete<rsa_st> >::type&& {aka std::default_delete<rsa_st>&&}’
/usr/include/c++/4.7/bits/unique_ptr.h:125:7: note: std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>::pointer, typename std::conditional<std::is_reference<_Dp>::value, _Dp, const _Dp&>::type) [with _Tp = rsa_st; _Dp = std::default_delete<rsa_st>; std::unique_ptr<_Tp, _Dp>::pointer = rsa_st*; typename std::conditional<std::is_reference<_Dp>::value, _Dp, const _Dp&>::type = const std::default_delete<rsa_st>&]
/usr/include/c++/4.7/bits/unique_ptr.h:125:7: note: no known conversion for argument 2 from ‘void(RSA*) {aka void(rsa_st*)}’ to ‘std::conditional<false, std::default_delete<rsa_st>, const std::default_delete<rsa_st>&>::type {aka const std::default_delete<rsa_st>&}’
/usr/include/c++/4.7/bits/unique_ptr.h:120:7: note: std::unique_ptr<_Tp, _Dp>::unique_ptr(std::unique_ptr<_Tp, _Dp>::pointer) [with _Tp = rsa_st; _Dp = std::default_delete<rsa_st>; std::unique_ptr<_Tp, _Dp>::pointer = rsa_st*]
/usr/include/c++/4.7/bits/unique_ptr.h:120:7: note: candidate expects 1 argument, 2 provided
/usr/include/c++/4.7/bits/unique_ptr.h:114:17: note: constexpr std::unique_ptr<_Tp, _Dp>::unique_ptr() [with _Tp = rsa_st; _Dp = std::default_delete<rsa_st>]
/usr/include/c++/4.7/bits/unique_ptr.h:114:17: note: candidate expects 0 arguments, 2 provided
../source/ac-pki.cpp:550:91: error: cannot convert ‘std::unique_ptr<rsa_st>::pointer {aka rsa_st*}’ to ‘EVP_PKEY* {aka evp_pkey_st*}’ for argument ‘2’ to ‘int PEM_write_PKCS8PrivateKey(FILE*, EVP_PKEY*, const EVP_CIPHER*, char*, int, int (*)(char*, int, int, void*), void*)’
make: *** [source/ac-pki.o] Error 1
You need to give the type of the deleter as well
std::unique_ptr<RSA, void (*)(RSA*)> rsa(RSA_new(), ::RSA_free);
Otherwise, std::unique_ptr uses std::default_delete
The type of the deleter is part of the unique_ptr's type. So change your code to
std::unique_ptr<RSA, decltype(&::RSA_free)> p(RSA_new(), ::RSA_free);
Or, to cut down on the verbosity
using RSA_ptr = std::unique_ptr<RSA, decltype(&::RSA_free)>;
RSA_ptr rsa(RSA_new(), ::RSA_free);