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.
Macro systems can be very powerful, but they are also quite hard to use. It is 2016 and error messages in C++ templates are still inferior to the messages you get in C#, Java or Scala generics, despite templates existing for much longer.
C++ templates are also not the very best at metaprogramming either. Take any macro system like the ones found in LISPs, Scala or Template Haskell - they are much more powerful and consistent with the rest of the language. I can code Scala metaprograms in Scala or LISP metaprograms in LISP. But I can't code C++ metaprograms in C++, I have to use this weird duck-typed functional template language which doesn't have even loops or conditionals.
I have experience in compiler design and C#, Java and C++ are my tools of trade. So I know their generics systems pretty well.
Maybe if I get bored during Easter I can bother to provide your safe list.
This sentence doesn't make much sense. Comparing oranges and apples. It is like saying Scala macros are better than Scala generics. C++ templates are neither great at metaprogramming (there are much better macro systems in other languages out there) nor great at generics (Java, C# or Swift generics are not state-of-the-art either, but in some cases I mentioned they are better).