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()相同的函数模板代码>,第二个将是指向第一个和第三个的指针,与第二个相同,只是当它们单独存在时返回类型不同。而且也没有办法让这些人成为演员。