ChatGPT解决这个技术问题 Extra ChatGPT

What's the relationship between C++ template and duck typing?

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?


t
tgmath

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.


hmm..my understanding from duck typing is, that you try to find out the type. That means you encounter a dynamic object and you're not sure about the type. In c++ templates you have to be sure about the type, in order to instantiate it.
-1. Duck typing does not necessarily imply dynamic typing or runtime checks. Compile-time duck typing is still duck-typing.
C++ templates were originally based on token replay. That still shows in its duck type like properties.
S
Steve Jessop

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.


I
In silico

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++.


From my limited understanding of duck-typing, your description of the copy-function sounds precisely as if it uses duck-typing. What is it exactly that characterizes duck-typing that is not "fulfilled" by C++ templates?
@aioobe: As I understand it, duck-typing is something that happens at runtime as opposed to compile-time. I say it's like duck-typing because the compiler still does type-checking at compile-time as though it's not doing any duck-typing. It's just that the types isn't known until one actually uses the template.
From the point of view of template instantiation, the compile-time/runtime-distinction corresponds to pre-instantiation and post-instantiation. IMHO the compile-time/runtime distinction is perhaps better off thought of as an instance of a 'compile-time/post-compile-time' distinction (i.e. 'behaviour is known/decided at or before compile time' vs 'afterwards'). Where eg. python checks when calling object.hello(), not when compiling to bytecode, C++ will check when trying to compile Type1& object::hello(Type1 x, Type2 y) { return x+y; } rather than when turning c = object.hello(a,b); into this.
While your position is conform to what appears to be an accepted understanding that duck-typing implies runtime checks, there is some valid criticism of that definition of the term itself, which makes the categorical "no" at beginning of your answer rather biased. The end of your answer attempts correct this bias. IMHO, you should have answered from the start in a more nuanced way.
R
RandomDSdevel

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.


s
sharptooth

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.


d
duedl0r

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.


M
Mechanical snail