Earlier quoted context omitted.
In C++, the signature of a function template doesn't necessarily tell you what types you can successfully call it with, nor what the return type is. Much analysis is delayed until all templates are instantiated, with famously terrible consequences for error messages, compile times, and tools like IDEs and linters. By contrast, rust's monomorphization achieves many of the same goals, but is less of a headache to use b…
> In C++, the signature of a function template doesn't necessarily tell you what types you can successfully call it with, nor what the return type is. That's the whole point of Concepts, though.
Example [0]:
#include
template
concept fooable = requires(T t) {
{ t.foo() } -> std::same_as;
};
struct only_foo {
int foo();
};
struct foo_and_bar {
int foo();
int bar();
};
template
int do_foo_bar(T t) {
t.bar(); // Compiles despite fooable not specifying the presence of bar()
return t.foo();
}
// Succeeds despite fooable only requiring foo()
template int do_foo_bar(foo_and_bar t);
// Fails even though only_foo satisfies fooable
template int do_foo_bar(only_foo t);
[0]: https://cpp.godbolt.org/z/jh6vMnajj