C返回类型的过载功能

C返回类型的过载功能,第1张

概述如果我认为我对C一无所知那么你就不能通过返回类型来重载函数. 那么有人能解释一下这里发生了什么吗? class A { public: typedef int _foo; };class B {};template<class T>typename T::_foo Foo(int){ cout << "Foo(int)\n"; return typename T::_foo(); 如果我认为我对C一无所知那么你就不能通过返回类型来重载函数.

那么有人能解释一下这里发生了什么吗?

class A { public: typedef int _foo; };class B {};template<class T>typename T::_foo Foo(int){    cout << "Foo(int)\n"; return typename T::_foo();}template<class T>typename T Foo(char){    cout << "Foo(char)\n"; return typename T();}int main(){    Foo<A>(0);      // Writes "Foo(int)",as expected.    Foo<B>(0);      // Writes "Foo(char),expected error unable to compile template.    return 0;}

有两个类A和B. A定义typedef _foo,B不定义.函数模板Foo,Foo(int)和Foo(char)有两个重载. Foo(int)返回T :: _ foo,Foo(char)返回T.

然后调用Foo(0)两次.这与Foo(int)完全匹配,所以我希望Foo< A>(0)编译好,而Foo< B>(0)编译失败,因为B没有定义模板中使用的类型_foo.

实际发生的是Foo< B>(0)完全忽略Foo(int)并实例化Foo(char).但是通过正常的重载决策规则,Foo(0)显然是Foo(int)的精确匹配,并且使Foo(char)成为更可行的匹配的唯一因素是不应该考虑的返回类型.

要验证它是影响重载决策的返回值,只需添加:

template<class T>voID bar(int)  { typename T::_foo a; cout << "bar(int)\n"; }template<class T>voID bar(char) { cout << "bar(char)\n"; }bar<A>(0);      // Writes "bar(int),as expected.//bar<B>(0);    // Error C2039: '_foo' : is not a member of 'B',as expected.

这清楚地表明,在没有返回值的情况下,Foo(int)确实是正确的重载,并且如果模板无法解析从其模板参数中使用的类型,则编译失败是正常结果.

解决方法 你没有在返回类型上重载,你是专门的函数模板,当Foo< B>(int)特化形成无效类型B :: _ foo时,从SFINAE设置的重载中删除特化,留下Foo< B>(char)作为唯一可行的功能. 更详细地,对Foo< A>(0)的调用首先执行名称查找以查找范围中的所有Foo名称,然后实例化任何函数模板以找到重载候选者,然后重载决策选择最佳匹配.

实例化函数模板的步骤产生以下两个函数声明:

int Foo<A>(int);A Foo<A>(char);

过载分辨率选择第一个作为最佳匹配.

但是,当调用Foo< B>(0)时,实例化会产生这些声明:

<invalID type>  Foo<B>(int);B Foo<B>(char);

第一个声明无效,因此只有一个候选者可以进行重载解析,因此这是一个被调用的声明.

在bar示例中,在实例化期间形成的无效类型不在函数声明的“直接上下文”中(它在函数定义中,即正文中),因此SFINAE不适用.

总结

以上是内存溢出为你收集整理的C返回类型的过载功能全部内容,希望文章能够帮你解决C返回类型的过载功能所遇到的程序开发问题。

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

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

原文地址: http://outofmemory.cn/langs/1234968.html

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

发表评论

登录后才能评论

评论列表(0条)

保存