模板头类型推导问题

问题描述 投票:0回答:1

我尝试使用部分规范编写模板,但遇到了 Visual C++ 类型列表推导的问题:

template <typename tuple_types>
struct TupleX;

template <typename... head_types, typename tail_type>
struct TupleX< std::tuple<head_types..., tail_type> >
{
    using Tail = tail_type;
};

using FooX = std::tuple<int, float, double>;
using BarX = typename TupleX<FooX>::Tail;

Visual C++ 2022 无法使用以下命令构建它:

error C2027: use of undefined type 'TupleX<FooX>' see declaration of 'TupleX<FooX>'
error C2061: syntax error: identifier 'Tail'

虽然顺序相反,但推导仍按预期进行:

template <typename tuple_types>
struct TupleX;

template <typename head_type, typename... tail_types>
struct TupleX< std::tuple<head_type, tail_types...> >
{
    using Head = head_type;
};

using FooX = std::tuple<int, float, double>;
using BarX = typename TupleX<FooX>::Head;

static_assert(std::is_same_v<BarX, std::tuple_element_t<0, FooX> >);

考虑到以上所有内容,我提出了几个问题,希望是正确的。

  1. 我提出的实现中是否存在一些逻辑错误?
  2. 其他编译器支持这种推导吗?
  3. 是标准定义的情况吗?(我忽略了一些文档,但没有找到答案)
c++ visual-c++ c++20 c++-templates visual-c++-2022
1个回答
0
投票

我提出的实现中是否存在一些逻辑错误?

问题在于你的逻辑的实现。

特别是,在第一种情况下

head_type
是一个参数包,这意味着它消耗所有传递的参数参数(这里是
FooX
)。这反过来意味着
tail_type
将为空,但这是不允许的,因为
tail_type
不是参数包,因此不能留空。

这本质上意味着,唯一的匹配是将使用的主模板。但由于您只有主模板的声明,因此我们收到了提到的不完整错误。


第二种情况有效,因为现在

tail_type
是一个参数包,可以留空。在这种情况下传递的
FooX
将与
head_type
匹配。

© www.soinside.com 2019 - 2024. All rights reserved.