
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.
有人可以澄清:
>如果我对函数模板参数推导的理解是正确的?
>如果是因为sizeof运算符的非评估性质使得传递0成功?和
>如果0在这种情况下无关紧要,我们可以选择任何参数代替0,例如0.0,100甚至用户定义的类型?
结论:我在C Primer中发现了一个关于函数模板显式参数的部分.我引用“正常转换申请明确指定的参数”和“出于同样的原因,正常转换允许参数
使用普通类型定义(第16.2.1节,第680页),正常转换也适用
对于其模板类型参数被显式指定的参数“.因此,此问题中的0实际上是隐式转换为指向成员的空指针(指针转换).
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)将不会在运行时调用,但其类型在编译时确定.
总结以上是内存溢出为你收集整理的c – sizeof运算符是否会导致模板参数推断?全部内容,希望文章能够帮你解决c – sizeof运算符是否会导致模板参数推断?所遇到的程序开发问题。
如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。
欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)