我正在尝试实现一个固定大小的多维数组,其大小在运行时确定。其中(2(make_shared
(template<class T> shared_ptr<T> make_shared(std::size_t N) // T is U[]
(过载。然而,我面临编译错误(日志如下(。如果我将shared
更改为它们的unique
对应项,则不存在错误。我的问题是,
- 这个错误是关于什么的
unique
为什么有效- 有什么更好的方法来实现这种运行时固定的多维数组容器
最小工作示例:
#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;
}
来自g++-10
的错误消息如下(为简洁起见,请注意已取消(
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
输出:
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)
和来自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
输出:
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
原始代码,如果有帮助的话,
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];
}
};
对于您的第一个问题"这个错误是关于什么的":
GCC libstdc++和Clang libc++不支持";扩展CCD_ 10以支持阵列";它在c++20中引入。因此,这些编译器将尝试使用template< class T, class... Args > shared_ptr<T> make_shared( Args&&... args );
,它试图转发您的参数(在本例中,cell_t
=std::size_t
(来构造std::shared_ptr<cell_t[]>[]
。这是做不到的,所以他们抱怨。
您可以在此处检查编译器兼容性:编译器对C++20 的支持