feisty2
24th June 2020, 19:22
it's not about strict typing, also the term "strict typing" is ill-formed.
code without type declarations are more expressive since they automatically generalize to any type that meets the requirements, you define a "typeless" entity once
auto f(auto&& x) {
return x + x;
}
it automatically works for any compatible case
auto x = f(1); // x is of type int, x == 2
auto y = f(3.14); // y is of type double, y == 6.28
auto z = f("aa"s); // z is of type std::string, z == "aaaa";
if you declare the parameter type and return type for "f", say "int", it would fail with an std::string argument even if the logic totally works for such case. and the returned result with a double argument would be incorrect.
also, if you want something that either completely meets the requirements, or "kinda" meets the requirements and you wanna manually take care of the incompatible part for the latter case, this is also impossible with explicit type declarations.
say you want a function "g", that accepts an object as its argument, if the object has a member named "x", print x, otherwise print "error!"
auto g(auto&& obj) {
if constexpr (requires { &obj.x; })
std::cout << obj.x;
else
std::cout << "error!"
}
now how you gonna define something like this with type declarations??
code without type declarations are more expressive since they automatically generalize to any type that meets the requirements, you define a "typeless" entity once
auto f(auto&& x) {
return x + x;
}
it automatically works for any compatible case
auto x = f(1); // x is of type int, x == 2
auto y = f(3.14); // y is of type double, y == 6.28
auto z = f("aa"s); // z is of type std::string, z == "aaaa";
if you declare the parameter type and return type for "f", say "int", it would fail with an std::string argument even if the logic totally works for such case. and the returned result with a double argument would be incorrect.
also, if you want something that either completely meets the requirements, or "kinda" meets the requirements and you wanna manually take care of the incompatible part for the latter case, this is also impossible with explicit type declarations.
say you want a function "g", that accepts an object as its argument, if the object has a member named "x", print x, otherwise print "error!"
auto g(auto&& obj) {
if constexpr (requires { &obj.x; })
std::cout << obj.x;
else
std::cout << "error!"
}
now how you gonna define something like this with type declarations??