C++ 之间有什么关系?模板和鸭子打字?

发布于 2024-11-28 03:52:24 字数 64 浏览 3 评论 0原文

对我来说,C++ 模板使用了鸭子类型的思想,这是对的吗?这是否意味着模板类或方法中引用的所有泛型类型都是鸭子类型?

To me, C++ template used the idea of duck typing, is this right? Does it mean all generic types referenced in template class or method are duck type?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

瞳孔里扚悲伤 2024-12-05 03:52:24

对我来说,C++ 模板是鸭子类型的编译时版本。
编译器将编译例如 Class 和只要你的 Duck
拥有所有需要的类型,它将实例化一个类。

如果某些内容不正确(例如缺少复制构造函数),则编译失败。
当你用一个函数调用一个函数时,真正的鸭子打字就会失败。
非鸭型。在这里它会在运行时发生。

To me C++ templates are a compile-time version of duck typing.
The compiler will compile e.g. Class and as long as your Duck
has all needed types it will instantiate a class.

If something is not correct(e.g. copy constructor missing) the compilation fails.
The counterpart in real ducktyping is a failure when you call a function with a
non-duck type. And here it would occur at runtime.

在风中等你 2024-12-05 03:52:24

鸭子打字的意思是,“如果它像鸭子一样嘎嘎叫并且像鸭子一样走路,那么它就是一只鸭子”。它在计算机科学中没有正式的定义供我们与 C++ 进行比较。

当然,C++ 与(例如)Python 并不相同,但它们都有隐式定义接口的概念。用作 Python 函数参数的对象所需的接口是函数用它执行的任何操作。用作 C++ 模板参数的类型所需的接口是模板对该类型的对象所做的任何操作。这就是相似性,也是评估 C++ 模板的依据。

此外,由于模板参数推导,在 C++ 中您可以尝试传递任何旧对象,编译器将确定它是否可以实例化函数模板。

一个区别是,在 C++ 中,如果参数不嘎嘎,则编译器会反对。在Python中,只有运行时对象(并且只有当函数被实际调用时,如果代码中有条件)。这是对象/类型所需的接口本质上的差异 - 在 C++ 中,模板要么要求特定表达式有效,要么不需要。在 Python 中,必要的有效表达式可以取决于早期必要表达式的运行时值。因此,在Python中,你可以要求一个大声或安静地嘎嘎叫的对象,如果它大声嘎嘎叫,它也需要走路。在 C++ 中,您可以通过条件 dynamic_cast 来做到这一点,如果卷是编译时常量,您可以对其进行模板专业化,但您不能使用静态类型来表示鸭子只需要如果 quack_volume() 返回 loud 则行走。当然,在 Python 中,所需的接口可能并不是真正的“必需”——如果方法不存在,行为就是抛出异常,并且如果发生这种情况,可以记录并保证调用者的行为。

由您决定是否定义“鸭子类型”,这样这种差异意味着 C++ 没有它。

Duck typing means, "if it quacks like a duck and walks like a duck, then it's a duck". It doesn't have a formal definition in computer science for us to compare C++ against.

C++ is not identical to (for example) Python, of course, but they both have a concept of implicitly-defined interfaces. The interface required of an object used as a Python function argument is whatever the function does with it. The interface required of a type used as a C++ template argument is whatever the template does with objects of that type. That is the similarity, and that is the grounds on which C++ templates should be assessed.

Furthermore, because of template argument deduction, in C++ you can attempt to pass any old object, and the compiler will figure out whether it can instantiate the function template.

One difference is that in C++, if the argument doesn't quack, then the compiler objects. In Python, only the runtime objects (and only if the function is actually called, if there are conditionals in the code). This is a difference in the nature of the interface demanded of an object/type - in C++ either the template requires that a particular expression is valid, or it doesn't require that. In Python, the necessary valid expressions can depend on the runtime values of earlier necessary expressions. So in Python you can ask for an object that either quacks loudly or quietly, and if it quacks loudly it needs to walk too. In C++ you can do that by a conditional dynamic_cast, and if the volume is a compile-time constant you could do it template specializations, but you can't use static typing to say that a duck only needs to walk if quack_volume() returns loud. And of course in Python the required interface may not really be "required" - behavior if a method isn't present is to throw an exception, and it might be possible to document and guarantee the caller's behavior if that happens.

Up to you whether you define "duck typing" so that this difference means C++ doesn't have it.

违心° 2024-12-05 03:52:24

对我来说,C++ 模板使用了鸭子类型的思想,这是对的吗?

不,C++ 模板用于实现通用代码。也就是说,如果您的代码可以处理多种类型,则不必为每种类型重复它。像 std::vectorstd::list 这样的东西就是明显的例子。 C++ 模板已被滥用来做其他事情,但通用性是其初衷。

是否表示模板类或方法中引用的所有泛型类型
是鸭子型吗?

不,它们只是“普通”类型,就像 C++ 中的所有其他类型一样。只是在模板实际实例化之前它们是未知的。

然而,模板可以用来实现诸如鸭子类型之类的东西。迭代器就是一个例子。考虑这个函数:

template<class InputIterator, class OutputIterator>
    OutputIterator copy(InputIterator first, InputIterator last,
                        OutputIterator result)
{
    while (first!=last) *result++ = *first++;
    return result;
}

请注意,copy 函数可以接受任何类型的参数,只要它实现不等运算符、解引用运算符和后缀增量运算符即可。这可能与 C++ 中的鸭子类型最接近。

To me, C++ template used the idea of duck typing, is this right?

No, C++ templates are used to implement generic code. That is, if you have code that can work with more than one type, you don't have to duplicate it for each type. Things like std::vector and std::list are obvious examples of this in action. C++ templates have been abused into doing other things, but genericity was the original intention.

Does it mean all generic types referenced in template class or method
are duck type?

No, they are just "normal" types just like every other type in C++. They are just not known until the template is actually instantiated.

However, templates can be used to implement something like duck typing. Iterators are an example. Consider this function:

template<class InputIterator, class OutputIterator>
    OutputIterator copy(InputIterator first, InputIterator last,
                        OutputIterator result)
{
    while (first!=last) *result++ = *first++;
    return result;
}

Note that the copy function can accept arguments of any type, as along as it implements the inequality operator, the dereference operator, and the postfix increment operator. This is probably as close to duck typing as you'll get in C++.

老街孤人 2024-12-05 03:52:24

不完全是。鸭子类型(动态类型样式)永远不会产生编译时类型错误,因为它们没有任何类型。对于模板,在实例化模板之前,您没有类型。一旦这样做,变量就会具有不同的类型,并且您确实会遇到编译时错误。

另外,对于鸭子类型,您可以让一个变量指向不同类型的对象,因为变量没有类型。这对于模板来说是不可能的——一旦实例化它们,变量就具有单一的特定类型。

不过,它们的相似之处在于约束是隐式的:仅检查实际使用的功能。与多态指针相反,实际类型并不重要。

Not exactly. Duck types (dynamic type style) will never yield compile-time type errors because they just don't have any type. With templates, you don't have types until you instantiate the template. Once you do, variables have distinct types, and you will indeed get compile-time errors.

Also, with duck types, you can have one variable point to different types of objects, because variables just have no types. That's not possible with templates — once you instantiate them, variables have a single specific type.

They are similar, though, in that constraints are implicit: only the features actually used are checked. As opposed to, say, polymorphic pointers, the actual type doesn't matter.

紅太極 2024-12-05 03:52:24

是的,有点 - 例如,如果类型 X 具有 AddRef()Release()QueryInterface()具有适当签名的方法,它可以用作具有 CComPtr 模板类的 COM 对象。但这并不是完整的鸭子类型 - 仍然对参数强制执行类型检查。

Yes, sort of - for example if type X has AddRef(), Release() and QueryInterface() methods with appropriate signatures it can be used as a COM object with CComPtr template class. But this is not complete duck typing - type checking is still enforced for parameters.

不弃不离 2024-12-05 03:52:24

不,这是一个不同的概念。鸭子类型是一种查找动态类型容器类型的方法。 C++ 模板不是动态类型的,它们使用特定类型进行实例化。

No, this is a different concept. duck typing is a method to find out the type of a dynamic typed container. C++ templates aren't dynamic typed, they get instantiated with a specific type.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文