问题描述
我有一些代码可以在 g++ 10.2.0 下编译和运行良好,但被 clang++ 11.0.0 拒绝。
这是该问题的最小重现:
#include <tuple>
#include <cstdint>
struct Dummy { };
using second_t = Dummy;
using example_t = std::tuple<size_t,second_t[8]>;
example_t f() {
example_t result;
return result;
}
int main() {
auto x = f();
(void) x;
}
在 g++ 中,它编译时没有任何抱怨,但使用 clang++ 我得到:
clang++ --std=c++20 -Wall -Werror main.cpp -o example
In file included from main.cpp:1:
/usr/bin/../lib/gcc/aarch64-unkNown-linux-gnu/10.2.0/../../../../include/c++/10.2.0/tuple:137:4: error: array initializer must be an initializer list
: _M_head_impl(std::forward<_UHead>(__h)) { }
^
/usr/bin/../lib/gcc/aarch64-unkNown-linux-gnu/10.2.0/../../../../include/c++/10.2.0/tuple:375:9: note: in instantiation of function template specialization 'std::_Head_base<1,Dummy [8],false>::_Head_base<Dummy [8]>' requested here
: _Base(std::forward<_Head>(_M_head(__in))) { }
^
/usr/bin/../lib/gcc/aarch64-unkNown-linux-gnu/10.2.0/../../../../include/c++/10.2.0/tuple:236:9: note: in instantiation of member function 'std::_Tuple_impl<1,Dummy [8]>::_Tuple_impl' requested here
: _Inherited(std::move(_M_tail(__in))),^
/usr/bin/../lib/gcc/aarch64-unkNown-linux-gnu/10.2.0/../../../../include/c++/10.2.0/tuple:996:17: note: in instantiation of member function 'std::_Tuple_impl<0,unsigned long,Dummy [8]>::_Tuple_impl' requested here
constexpr tuple(tuple&&) = default;
^
main.cpp:11:12: note: in defaulted move constructor for 'std::tuple<unsigned long,Dummy [8]>' first required here
return result;
^
1 error generated.
make: *** [Makefile:2: all] Error 1
有趣的是,如果我将 second_t
更改为 int32_t
,我也会收到来自 g++ 的错误:
g++ --std=c++20 -Wall -Werror main.cpp -o example
In file included from main.cpp:1:
/usr/include/c++/10.2.0/tuple: In instantiation of ‘constexpr std::_Head_base<_Idx,_Head,false>::_Head_base(_UHead&&) [with _UHead = int [8]; long unsigned int _Idx = 1; _Head = int [8]]’:
/usr/include/c++/10.2.0/tuple:375:49: required from ‘constexpr std::_Tuple_impl<_Idx,_Head>::_Tuple_impl(std::_Tuple_impl<_Idx,_Head>&&) [with long unsigned int _Idx = 1; _Head = int [8]]’
/usr/include/c++/10.2.0/tuple:237:42: required from ‘constexpr std::_Tuple_impl<_Idx,_Tail ...>::_Tuple_impl(std::_Tuple_impl<_Idx,_Tail ...>&&) [with long unsigned int _Idx = 0; _Head = long unsigned int; _Tail = {int [8]}]’
/usr/include/c++/10.2.0/tuple:996:17: required from here
/usr/include/c++/10.2.0/tuple:137:42: error: array used as initializer
137 | : _M_head_impl(std::forward<_UHead>(__h)) { }
| ^
make: *** [Makefile:2: all] Error 1
我猜这是因为使用了 C 数组。如果我将代码更改为使用 std::array
,问题就会消失。不过,出于好奇,我仍然很好奇是否有办法用 C-array 做到这一点。
所以我的问题是:
解决方法
C 数组基本上是指针,请注意,它们不提供也不需要有关数组长度的信息。长度必须单独保存并传递。因此,实现您需要的一种方法是:
using example_t = std::tuple<size_t,second_t*>;