为什么将struct与可变参数template参数一起使用会同时使两个模板实例化?

乌查

我想知道为什么该程序无法按预期工作。

#include <iostream>
#include <utility>
#include <list>

template <typename... Args>
struct prank
        : std::integral_constant<std::size_t, 9> {};

template <template <typename...> class C,typename T, typename ...Args>
struct prank<C<T,Args...>>
        : std::integral_constant<
        std::size_t,
        1+ prank<Args...>::value> {};

int main()
{
    using T = std::list<int>;
    std::cout << prank<T>::value << "\n";
}

异丁酮

输出为11,但应为10。

让我解释一下原因:

main()通话prank<T>std::list<int>

它有2种选择,根据解析规则,选择模板的第二种专业化。

然后在:

  template <template <typename...> class C,typename T, typename ...Args>
    struct prank<C<T,Args...>>

Cstd::listTintArgsempty

然后我们从继承

std::integral_constant<
            std::size_t,
            1+ prank<Args...>::value>

第二个变量std::integral_constant变为1 + prank<Args...>prank<Args...>它会使用空的Arguments包调用第一个恶作剧的结构,并从std::integral_constant该结构的value成员继承后成为9。

所以1+ prank<Args...>::value应该变成1 + 9 = 10而不是11!

但是似乎同时prank<Args...>制作和使用2个结构!struct prank<C<T,Args...>>struct prank

是一个错误还是我犯了一个错误?(我正在使用gcc 4.8.1)

菲利普·罗森-refp

介绍

问题是您假设std::list只有一个模板参数,导致的实例化prank<std::list<int>>,而这将导致的实例化prank<int>

但是,这是不正确的,这是因为std::list有一个默认模板参数以下的int,即分配:std::allocator<int>

template<class T, class Allocator = std::allocator<T>>
class std::list;
std::list<int> => std::list<int, std::allocator<int>>

解释

template <typename... Args>
/* (A) -> */ struct prank : std::integral_constant<std::size_t, 9> {};

template <template <typename...> class C,typename T, typename ...Args>
/* (B) -> */ struct prank<C<T,Args...>>
        : std::integral_constant<std::size_t, 1+ prank<Args...>::value> {};

实例化,顺序为

  1. (B) prank<std::list<int, std::allocator<int>>>
  2. (B) prank<std::allocator<int>>
  3. (一种) prank<int>

总价值收益?11

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

为什么模板参数推导不能与仅指定前两个参数的可变参数模板类一起使用?

为什么我的可变参数模板实例化不起作用?

编译时检查是否有两个具有相同模板参数的模板实例化

将COUNT与OVER一起使用时,将两个参数与PARTITION BY一起使用是什么意思?

如何与xargs一起使用两个参数?

将类型特征与可变参数模板参数一起使用

无法将std :: bind与可变参数模板参数一起使用

将javascript映射与具有两个参数的函数一起使用

将整数序列与元组和可变参数模板一起使用

如何使用可变参数模板将std :: variant与std :: visit一起进行?

将条件定义与可变参数模板一起使用

为什么类型约束 `std::convertible_to` 只能与一个模板参数一起使用?

使用 boost 的模板实例化:传递额外的参数

如何使用运行参数从模板实例化对象数组

为什么仅针对一个参数,可变参数模板与非可变模板不同?

将vector :: insert与可变参数一起使用

一起扩展两个参数包

交换可变参数模板中的两个参数

如何返回将两个函数与两个参数组合在一起的函数

boost :: hana tuple解压缩用于可变参数模板实例化

将natvis与模板参数包一起使用

unfoldr中的lambda函数如何与Haskell中的两个参数一起使用?

是否可以将参数化的URL模板与angular $ http服务一起使用

模板化函数参数的显式模板实例化

.join()为什么不与函数参数一起使用?

为什么与nvm一起使用时pnpm有两个商店?

将pip与两个都指向同一个域的--extra-index-url参数一起使用

为什么将turbofish与一起使用会产生“错误数量的类型参数”?

连接两个类型的可变参数模板包