C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了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.

有人可以澄清:

>如果我对函数模板参数推导的理解是正确的?
>如果是因为Sizeof运算符的非评估性质使得传递0成功?和
>如果0在这种情况下无关紧要,我们可以选择任何参数代替0,例如0.0,100甚至用户定义的类型?

结论:我在C Primer中发现了一个关于函数模板显式参数的部分.我引用“正常转换申请明确指定的参数”和“出于同样的原因,正常转换允许参数
使用普通类型定义(第16.2.1节,第680页),正常转换也适用
对于其模板类型参数被显式指定的参数“.因此,此问题中的0实际上是隐式转换为指向成员的空指针(指针转换).

解决方法

模板参数演绎在实例化函数时完成.这是作为函数重载的一部分完成的(以及其他不适用的上下文).在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)将不会在运行时调用,但其类型在编译时确定.

大佬总结

以上是大佬教程为你收集整理的c – sizeof运算符是否会导致模板参数推断?全部内容,希望文章能够帮你解决c – sizeof运算符是否会导致模板参数推断?所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。