我正在创建一个作为多维跨度工作的类。它需要一个指向一些连续数据的指针,例如
std::vector
s 数据,并允许您将其作为多维数组访问。使用下标运算符时,我想删除一维。以下代码显示了此的简化版本。
template <int... strides>
struct Span{};
template <int first, int... others>
struct DropFirst {
using type = Span<others...>;
};
template <int first, int... others>
using DropFirst_t = typename DropFirst<first, others...>::type;
template <int... N>
auto subscript() {
return DropFirst_t<N...>{};
}
到目前为止,我一直在使用 Visual Studio(MSVC 和 C++20),并且它按预期工作。我没有收到编译器错误或警告。现在我尝试使用 gcc 和 clang 在编译器资源管理器中编译它,但都无法编译它并给出类似的错误消息(编译器资源管理器 - 一致性视图)。
gcc 错误消息
<source>: In function 'auto subscript()':
<source>:14:28: error: pack expansion argument for non-pack parameter 'first' of alias template 'template<int first, int ...others> using DropFirst_t = typename DropFirst::type'
14 | return DropFirst_t<S...>{};
| ^
<source>:9:15: note: declared here
9 | template <int first, int... others>
| ^~~~~
Compiler returned: 1
如果我将
return
语句更改为以下内容,代码将为所有三个编译器进行编译:
return typename DropFirst<S...>::type{};
但我想用以前的方式。
错误消息表明我尝试扩展非包参数,但我扩展了
N
和 others
,它们是参数包,而不是 first
。所以我认为 MSVC 正在正确编译它,但 gcc 和 clang 都拒绝它的事实让我认为 MSVC 可能无法正常工作。
您不需要
first
中的 DropFirst_t
。
template <int... strides>
using DropFirst_t = typename DropFirst<strides...>::type;
工作得很好并且避免了错误。