我想知道为什么该程序无法按预期工作。
#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...>>
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...>
它会使用空的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)
问题是您假设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> {};
实例化,顺序为:
prank<std::list<int, std::allocator<int>>>
prank<std::allocator<int>>
prank<int>
总价值收益?11。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句