3 ms·
I think that Zig will eventually add a way to constrain types. A note about C++. Prior to C++20 concepts, you could always add constraints to templates via [SF
by mo_al_ 4y ago
I think that Zig will eventually add a way to constrain types.
A note about C++. Prior to C++20 concepts, you could always add constraints to templates via [SFINAE](https://en.cppreference.com/w/cpp/language/sfinae https://en.cppreference.com/w/cpp/language/sfinae), it had the tendency to be verbose:
template<typename T, typename =
enable_if_t<is_integral_v<T>>>
T add_2(T x) {
return x + 2;
}
struct Writer {
virtual void write(const char *) = 0;
};
struct SubWriter: public Writer {
virtual void write(const char *s) override {
puts(s);
}
};
template<typename T, typename =
enable_if_t<is_base_of_v<Writer, T>>>
void write_to(T x, const char *msg) {
x.write(msg);
}
int main() {
printf("%d\n", add_2(4)); // works
write_to(SubWriter{}, "Hello"); // works
}
With C++20 concepts:
integral auto add_2(integral auto x) {
return x + 2;
}
struct Writer {
virtual void write(const char *) = 0;
};
template<typename T>
concept Writable1 = is_base_of_v<Writer, T>; // uses
type_traits
template<typename T>
concept Writable2 = requires (T t) { // uses compile time
requirements, similar to Go interfaces
{ t.write("Hello") };
};
struct SubWriter1: public Writer { // satisfies Writable1
and Writable2
virtual void write(const char *s) override {
puts(s);
}
};
struct SubWriter2 { // satisfies only Writable2
void write(const char *s) {
puts(s);
}
};
// accepts both SubWriter1 and SubWriter2
void write_to(Writable2 auto x, const char \*msg) {
x.write(msg);
}
int main() {
printf("%d\n", add_2(4)); // works
write_to(SubWriter1{}, "Hello"); // works
}