Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/147.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++;按返回类型列出的重载函数 如果我认为我对C++有任何了解,那就是你不能通过返回类型来重载函数。_C++ - Fatal编程技术网

C++;按返回类型列出的重载函数 如果我认为我对C++有任何了解,那就是你不能通过返回类型来重载函数。

C++;按返回类型列出的重载函数 如果我认为我对C++有任何了解,那就是你不能通过返回类型来重载函数。,c++,C++,有人能解释一下这里发生了什么吗 class A{public:typedef int_foo;}; B类{}; 模板 类型名T::u foo foo(int) { cout您没有重载返回类型,您正在专门化一个函数模板,当Foo(int)专门化形成无效类型时B::\u Foo该专门化将从SFINAE设置的重载中删除,将Foo(char)函数作为唯一可行的函数 更详细地说,调用Foo(0)首先执行名称查找以查找范围中的所有Foo名称,然后实例化任何函数模板以查找重载候选项,然后重载解析选择最佳匹配项

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

class A{public:typedef int_foo;};
B类{};
模板
类型名T::u foo foo(int)
{

cout您没有重载返回类型,您正在专门化一个函数模板,当
Foo(int)
专门化形成无效类型时
B::\u Foo
该专门化将从SFINAE设置的重载中删除,将
Foo(char)
函数作为唯一可行的函数

更详细地说,调用
Foo(0)
首先执行名称查找以查找范围中的所有
Foo
名称,然后实例化任何函数模板以查找重载候选项,然后重载解析选择最佳匹配项

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

int Foo<A>(int);
A Foo<A>(char);
<invalid type>  Foo<B>(int);
B Foo<B>(char);
intfoo(int);
A Foo(char);
重载解析选择第一个作为最佳匹配

但是,当调用
Foo(0)
时,实例化会生成以下声明:

int Foo<A>(int);
A Foo<A>(char);
<invalid type>  Foo<B>(int);
B Foo<B>(char);
Foo(int);
B Foo(char);
第一个声明无效,因此重载解析只有一个候选项,即被调用的候选项

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

template<class T>
typename T::_foo Foo(int);

template<class T>
typename T Foo(char);
由于您要传递一个整数作为参数,因此第一个是更好的匹配,因此编译器使用该参数

Foo<B>(0);
很明显,第一个甚至没有意义,所以它丢弃了它并使用了第二个重载。这实际上与返回类型无关,它与模板原型的填写方式有关,然后再决定您所指的函数。下面是重新排列的示例,以澄清:

template<class T>
int foo(T::_foo) {}
template<class T>
int foo(char) {}

int main() {
    foo<A>(0); //uses the first, `int foo(int)` better than `int foo(char)`
    foo<B>(0); //uses the second, because the first doesn't work with B.
模板
intfoo(T::foo){}
模板
int foo(char){}
int main(){
foo(0);//使用第一个`intfoo(int)`比`intfoo(char)更好`
foo(0);//使用第二个,因为第一个不适用于B。

这被称为SFINAE,请注意,它只在模板参数、返回类型和函数参数中的非常特殊的情况下工作,而不是函数体本身。这就是为什么要进行“验证”导致错误,因为它无法从原型中判断其中一个函数无效,并且在决定重载时,原型是唯一要考虑的因素。

。这些不是按返回类型的重载。这些是按参数类型的重载,与往常一样。他没有提供函数模板的不同专门化,他说如果是SFINAE,那么为什么Bar(0)会导致编译失败,而不是简单地解析为Bar(char)?@MooingDuck,对,我对它进行了重新措辞。我指的是
Foo(int)
的不同专门化。显然
Foo(int)
Foo(char)
在返回类型上没有重载。@中微子,因为SFINAE只应用于函数的签名。
template<class T>
int foo(T::_foo) {}
template<class T>
int foo(char) {}

int main() {
    foo<A>(0); //uses the first, `int foo(int)` better than `int foo(char)`
    foo<B>(0); //uses the second, because the first doesn't work with B.