c – sizeof运算符是否会导致模板参数推断?

c – sizeof运算符是否会导致模板参数推断?,第1张

概述我知道sizeof运算符不会计算其表达式参数来获得答案.但它不是模板的非扣除上下文之一.所以我想知道它如何与模板交互,特别是模板参数推断.例如,以下内容取自C模板:完整指南: template<typename T> class IsClassT { private: typedef char One; typedef struct { char a[2]; } Two 我知道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运算符是否会导致模板参数推断?所遇到的程序开发问题。

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

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/1224619.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-06-05
下一篇2022-06-05

发表评论

登录后才能评论

评论列表(0条)

    保存