我尝试使用部分规范编写模板,但遇到了 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> >);
考虑到以上所有内容,我提出了几个问题,希望是正确的。
我提出的实现中是否存在一些逻辑错误?
问题在于你的逻辑的实现。
特别是,在第一种情况下
head_type
是一个参数包,这意味着它消耗所有传递的参数参数(这里是FooX
)。这反过来意味着 tail_type
将为空,但这是不允许的,因为 tail_type
是 不是参数包,因此不能留空。
这本质上意味着,唯一的匹配是将使用的主模板。但由于您只有主模板的声明,因此我们收到了提到的不完整错误。
第二种情况有效,因为现在
tail_type
是一个参数包,可以留空。在这种情况下传递的 FooX
将与 head_type
匹配。