Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/133.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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.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++_Templates_Syntax_Language Lawyer - Fatal编程技术网

C++ 为什么我们需要C++;?

C++ 为什么我们需要C++;?,c++,templates,syntax,language-lawyer,C++,Templates,Syntax,Language Lawyer,函数模板: template<class T> T max(T a, T b){return (a > b)? a: b;} 模板T max(ta,tb){return(a>b)?a:b;} 使用时: max<int>(a, b); // Yeah, the "<int>" is optional most of the time. max(a,b);//是的,“”大多数时候是可选的。 但如果您允许,我们可以这样编写模板: T max<c

函数模板:

template<class T> T 
max(T a, T b){return (a > b)? a: b;}
模板T
max(ta,tb){return(a>b)?a:b;}
使用时:

max<int>(a, b); // Yeah, the "<int>" is optional most of the time.
max(a,b);//是的,“”大多数时候是可选的。
但如果您允许,我们可以这样编写模板:

T max<class T>(T a, T b){return (a > b)? a: b;} 
//I know the return type T is not in its scope, don't focus on that.
tmax(ta,tb){return(a>b)?a:b;}
//我知道返回类型T不在它的范围内,不要关注它。
因此,我们可以像普通函数一样维护相同形式的声明和使用。甚至不需要引入和键入关键字“template”。我想类模板会是一样的吗?那么,还有其他原因使模板成为我们今天所知道的形式吗

我更改了表单,这样您就不会关注返回类型:

auto max<class T>(T a, T b) -> T {return (a > b)? a: b;}
//This is C++11 only and ugly i guess. 
//The type deduce happens at compile time 
//means that return type really didn't to be a problem.
automax(ta,tb)->T{return(a>b)→a:b;}
//这只是C++11,我想这很难看。
//类型推断发生在编译时
//这意味着返回类型真的不成问题。

我想到的直接答案是:
仅仅因为提出模板提案的人这么说了,标准委员会中没有人认为输入那些额外的
8
字符将是一项开销

另一方面:

模板的语法是复杂的,首先是吓人的,确保关键字<代码>模板的存在使读者更容易理解他们正在处理的模板,而不是C++提供的其他任何一个或任何实现特定的构造(读取编译器扩展)。我相信问题在于编译器实现的容易:C++中使用的任何名称必须至少被声明,才能帮助编译器从一开始就解析(因为我不知道)。这就是为什么要使用奇怪的新语法来声明函数的原因之一,它允许在参数之后定义返回类型


因此,这里的原因是,阅读您的示例时,T是使用的第一个名称,但它之前没有声明,因此编译器不知道它是什么或者它是什么类型的表达式。

在使用它之前,您必须声明
T
,因此它确实必须是

<class T> T max(T a, T b){return (a > b)? a: b;} 
tmax(ta,tb){return(a>b)?a:b;}

但是现在还不清楚什么是
,编译器很可能会对此感到困惑<前面的代码>模板清楚地表明,
使用这种方法很快就会遇到解析问题:

template <typename> int f(); // Current declaration syntax, type template argument.
template <int> int f();      // Current declaration syntax, non-type template argument.

void f<class>(); // New declaration syntax, type argument. 
void f<int>(); // New declaration syntax, non-type argument.
(void) f<int>(); // (void) is a cast , f is instantiation of f<class> with type int.
模板int f();//当前声明语法,类型模板参数。
模板int f();//当前声明语法,非类型模板参数。
void f();//新的声明语法,类型参数。
void f();//新声明语法,非类型参数。
(void)f();//(void)是一个强制转换,f是类型为int的f的实例化。

这正是所选择的语法。我相信这背后没有真正令人信服的理由。这只是一个简单的决定。当dey接受c++11时,你已经晚了几个月。现在,你必须等待接下来的20年。我不记得这种变体在C++的设计和进化中被检查过,这是当时(大约20年前)决定的事情的最佳来源。问答网站不是主观问题的好格式。然而,你不是唯一一个要求这样做的人。David Abrahams(MPL背后的人)有一篇有趣的博客文章,关于模板代码的较短语法:他甚至在叮当声邮件列表上写了关于它的文章,并请求帮助更改解析器/语义分析以试验这种语法,并检查它是否引起歧义等:)@MatthieuM。知道原因会更好。有时我不明白为什么我们需要声明(许多语言不需要声明),但当我得到答案,它的目标是帮助不打扰我时,我在编码时有了更好的心情,更了解如何编写好的代码。有些语言根本不需要
模板
,它们非常好。Scala,Rust。有很多,我只是不记得很多。这绝对不是必须的。顺便说一下,在C++中,有时在声明之前使用标识符(考虑内联类方法调用对方:它们不需要前向声明),所以即使对于C++ C++,“T必须先声明”听起来像是一个弱的原因。好的观察,但我认为这些是C++中的例外。一般来说,我认为您必须在访问之前声明,至少在C++中。其他语言当然不受这样的限制。@cschwan使函数作为一个整体与类一样并没有坏处。在使用前声明只是为了确保不会意外地引入新名称(如拼写错误或打字错误或其他),这种语法不会违反规则。这不是问题<代码>(void)f()将被视为与
模板void f()相同如果它是单独的。当用作右值时,将被视为类型转换。正常函数也会遇到同样的问题。@Mike:试着让解析过程完全清晰。那么
f()呢<代码>f(*f)()<代码>(f*)(*f)()
f
应该是一种预定义的类型,因为它的右边没有括号。我不确定类名和函数名是否可以重载。如果允许,它将是一个与
template f()相同的函数模板,第二个将是指向第一个和第三个的指针,与第二个相同,只是当它们单独存在时返回类型不同。而且也没有办法让这些人成为演员。