Further support for the idea that C++ templates are an automated copy+paste mechanism is that you're allowed to give templates arguments that are not types.
Further reading: https://msdn.microsoft.com/en-us/library/c6cyy67b.aspx
Further support for the idea that C++ templates are an automated copy+paste mechanism is that you're allowed to give templates arguments that are not types.
Further reading: https://msdn.microsoft.com/en-us/library/c6cyy67b.aspx
C# type checks imply a performance hit and are an implementation detail. Nothing prevents a C# compiler to choose another one. It has nothing to do with generics vs templates.
For example Modula-3 and Ada compilers use the same approach as C++ for code generation of their generics.
So where is that example of something that can only be written with C# generics, but not with C++ templates?
A github gist maybe?
That is what enable_if, type traits, if constexpr and eventually concepts allow for.
#include <string>
template <typename T>
void foo(const T& arg) {
int x = std::string("int expected");
}
$ g++ -c template.cpp
$ // see, no error
Templates are only syntax-checked. The type checker is not even executed on the non-generic code inside of templates. The type checker will be executed after the template is instantiated (expanded). At that point, generic types do not exist. There exist only concrete types.Uninstantiated templates are dead code that will be stripped anyway.
Sure, you can type-check them for particular type arguments. But you can't type-check them generally at the generic level and you have absolutely no guarantee that your library code is free of type errors. Not a problem if the goal is to produce the final executable, but a big problem for a library writer, who doesn't control the inputs (in this case: the types provided by the user of the library).
And AFAIK C++17 concepts do not address this problem, really. I can constrain my input types with them, and the calling code will be forced to conform to them (and the compiler will present a nice error message if it doesn't), but there is still no checking on the other side - that is if the template implementation is correct assuming these constraints. I can publicly declare my code requires T.bar(), then shamelessly call T.baz() in the template implementation and the compiler will not catch it.
This is like a Python program. You don't know if it type-checks before you run it, but even if you run it once or twice and it was fine, that doesn't guarantee there are no type errors.
The code line int x = std::string("int expected"); has zero relation with any of the template arguments.
So a programmer error that doesn't have anything to do with the types provided for the template.
Sure it will be caught in C#, because its build model assumes the existence of modules and everything is compiled to binary.
In C++ a similar compilation error would occur when compiling the translation unit into a library where the template is instantiated.
Of course, most templates being header only the error will only occur when instating it, but it will still blow on compilation and prevent the final generation of the exe, dll being produced.
Also errors related to semantic type check, independent of template arguments is relatively easy to achieve with unit tests.
I still fail to see how a generic system that doesn't offer partial specialization or meta-programming as being more powerful than templates.
By not doing runtime checks you get to skip that work at runtime, obviously, but you also get to enable other optimizations like inlining the monomorphised version.