c – sizeof运算符是否会导致模板参数推断?
我知道sizeof运算符不会计算其表达式参数来获得答案.但它不是模板的非扣除上下文之一.所以我想知道它如何与模板交互,特别是模板参数推断.例如,以下内容取自C模板:完整指南:
template<typename T> class IsClassT { private: typedef char One; typedef struct { char a[2]; } Two; template<typename C> static One test(int C::*); template<typename C> static Two test(...); public: enum { Yes = sizeof(IsClassT<T>::test<T>(0)) == 1 }; enum { No = !Yes }; }; 正如其名称所示,此类型函数确定模板参数是否为类类型.该机制基本上是以下条件测试: sizeof(IsClassT<T>::test<T>(0)) == 1 但是请注意,函数模板参数是显式的(在本例中为T),函数参数是int类型的plan 0,它不是指向类C的int成员的类型指针.在正常的函数模板参数推导中,T实际上是类类型,函数参数只是一个0,在静态的一个测试中推导出(int C :: *);应该失败,因为在模板参数推断期间不允许隐式转换(0用作空指针类型)并且(我猜?)SFINAE应该启动并且选择了重载决策 static Two test(...); 但是,由于整个表达式都包含在sizeof运算符中,所以似乎在没有强制转换的情况下传递0. 有人可以澄清: >如果我对函数模板参数推导的理解是正确的? 结论:我在C Primer中发现了一个关于函数模板显式参数的部分.我引用“正常转换申请明确指定的参数”和“出于同样的原因,正常转换允许参数 解决方法
模板参数演绎在实例化函数时完成.这是作为函数重载的一部分完成的(以及其他不适用的上下文).在TAD中,函数参数的类型用于推导模板参数,但并非所有参数都必须使用.这就是“非演绎语境”的来源.如果模板参数出现在函数签名中的非推导上下文中,则无法从实际参数中推断出该模板参数.
sizeof(T)实际上是T的非推导上下文,但它显而易见,甚至没有人愿意提及它.例如. template< int N> class A {}; template<typename T> void f(A<sizeof(T)>); f(A<4>()); 编译器不会选择sizeof(T)== 4的随机T. 现在,您的示例实际上在函数模板的参数列表中没有sizeof,因此“非推导上下文”是一个无关紧要的考虑因素.也就是说,理解“sizeof不评估其表达式参数”意味着什么是很重要的.这意味着不计算表达式值,但表达式类型是.在您的示例中,IsClassT< T> :: test< T>(0)将不会在运行时调用,但其类型在编译时确定. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |