为啥 C++1* 仍然需要模板关键字来代替 Full Duck Typing

Posted

技术标签:

【中文标题】为啥 C++1* 仍然需要模板关键字来代替 Full Duck Typing【英文标题】:Why Does C++1* Still Need the template Keyword in Lieu of Full Duck Typing为什么 C++1* 仍然需要模板关键字来代替 Full Duck Typing 【发布时间】:2016-05-06 03:03:23 【问题描述】:

许多年前,(至少对我而言)静态 C++ 多态性似乎是一致的。 Python 等语言依赖于duck typing,你有:

def fn(foo, bar):
    foo.baz(bar.bo())

这个想法是,如果它适当地“嘎嘎”,那么语言就可以了。

相反,在 C++ 中,您必须解释它是什么“动物”:

void fn(foo_type foo, bar_type bar);

对于“家庭王国”,您需要明确使用 template 关键字:

template<class Foo, class Bar>
void fn(Foo foo, Bar bar);

有了像auto ...() -&gt; decltype 这样的新功能返回类型,尤其是generic lambdas,似乎有一些更像非模板Python 的鸭子类型:

[] (auto container)  return container.size(); ;

那么,我的问题是,为什么仍然需要 template 关键字?为什么不完全接受(可选)鸭式打字:

// Takes a foo_type and a bar_type 
void fn(foo_type foo, bar_type bar);

// Takes some "foo-quacking" type, and a bar_type
void fn(auto foo, bar_type bar);

// Etc.

【问题讨论】:

你检查过 C++1z/C++2x 的概念提案吗? @Yakk,谢谢-我没有关注概念的位置。会读起来。 它即将到来,但并非所有事情都同时发生。在 C++11 中,我们得到了 lambdas 的推导返回类型,然后在 C++14 中,我们得到了所有函数的返回类型。在 C++14 中,我们得到了泛型 lambda(即 auto 参数),Concepts TS 为普通函数添加了相同的(这样的函数隐式成为函数模板并为提供的参数实例化)。 谢谢@JonathanWakely,这很有道理。 无论是auto 还是template,您都需要某种方式向编译器表明该声明不是具体的,而是通用的(参数化的)声明。这确实留下了将哪些名称作为参数的问题。 【参考方案1】:

作为Concepts 功能的一部分,它实际上几乎就在门口,并且一些编译器已经实现了它!例如,在 GCC 4.9 中,如果您指定 -std=c++1y,您实际上可以编译并运行以下内容:

auto print_arg(auto arg) 
  std::cout << arg;

【讨论】:

在此之后我们将摆脱auto关键字:) @Pierre 还有一些讨论,上次我检查时,围绕将基于范围的 for 简化为简单的 for (v : V),这可能等同于 for (auto&amp;&amp; v : V) 这不仅仅是“正在讨论”,它是一个 ISO 技术规范。您展示的功能在 GCC 4.9 中被破坏,但将在 GCC6 中得到完全支持(以及其余的 Concepts TS)。 @YamMarcovic,基于范围的for 的较短形式的proposed 被拒绝了。 @JonathanWakely 谢谢,改写得更准确。

以上是关于为啥 C++1* 仍然需要模板关键字来代替 Full Duck Typing的主要内容,如果未能解决你的问题,请参考以下文章

为啥要用dbus,如果不用dbus要用啥来代替?

c_cpp 这在Windows,Linux,* BSD和Mac OS X上提供了endian.h的endian转换函数。你仍然需要使用-std = gnu99代替

为啥用字符串代替不了路径

ad中跳线为啥用电阻代替

PHP 类为啥使用 public 关键字?

为啥要使用 DllImport 属性来代替添加引用?