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?
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.
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.
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.
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.
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.
Wikipedia covers this distinction.