为什么使用带可变模板参数的结构体同时实例化两个模板
Why using struct with variadic template parameter makes two template instantiation at the same time?
我想知道为什么这个程序不像预期的那样工作。
#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";
}
ideone
输出是11,但它应该是10。
让我解释一下为什么:
在main()
中我们称prank<T>
为std::list<int>
。
它有两个选择,根据解析规则,它选择模板的第二个专门化。
Then in:
template <template <typename...> class C,typename T, typename ...Args>
struct prank<C<T,Args...>>
C
变为std::list
, T
变为int
, Args
变为empty
然后从
继承std::integral_constant<
std::size_t,
1+ prank<Args...>::value>
std::integral_constant
的第二个变量变成1 + prank<Args...>
, prank<Args...>
自己调用第一个恶作剧的结构体,带空参数包,继承std::integral_constant
后该结构体的值成员变成9。
所以1+ prank<Args...>::value
应该变成1+9=10而不是11 !
但prank<Args...>
似乎同时制造和使用2个结构体!(struct prank<C<T,Args...>>
and struct prank
)
这是一个bug还是我犯了一个错误?(我使用gcc 4.8.1)
简介
问题是您假设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> {};
实例化,顺序为:
- (b)
prank<std::list<int, std::allocator<int>>>
- (b)
prank<std::allocator<int>>
- (a)
prank<int>
总产值?11 .
相关文章:
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 在 C++ 中使用 OpenMP 并行化两个 for 循环不会提供更好的性能
- 编译时检查是否有两个具有相同模板参数的模板实例化
- 如何获得C - 模板状行为,但仅允许实例化两种特定类型
- 如何在 main 函数的一个对象中初始化两个类的值?C++
- 如何实例化多个 set 对象来测试 Set 类的各种构造函数和方法
- 如何线性化两个浮点变量的乘积
- 当实例化两次时,C 提升线程会导致分割故障
- 两个未初始化的实例之一
- 如何使用线程来实例化多个 QApplication
- 如果条件为true,则c++实例化几个类
- 如何在不实例化两个c++类型的情况下确定这两个类型
- 初始化两个双向链表C++
- 成员初始值设定项列表:从返回元组的函数初始化两个成员
- 如何通过定义派生类的构造函数来实例化两个基类的私有数据成员
- c++在for循环中初始化两个不同的迭代器
- 为什么我可以在一个文件中无序地初始化两个静态类变量,而不能初始化三个
- 初始化两个不同应用程序的cpp文件共享的headerfile中的数组结构
- 为什么使用带可变模板参数的结构体同时实例化两个模板
- 实例化多个模板