5 ms·
I think you'll find implementing a type-safe print function in C++11 very challenging. What you could do in constexpr was very limited, type deduction was less
by hn_go_brrrrr 4y ago
I think you'll find implementing a type-safe print function in C++11 very challenging. What you could do in constexpr was very limited, type deduction was less powerful, and it didn't have fold expressions. I'd say this really only became feasible since C++17.
- saghm 4y agoMaybe the top comment in this thread wasn't so facetious after all then; it did take almost 40 years for C++ to advance enough to have a decent print function
- Kranar 4y agoBoost had a type-safe printf function dating back to October 10th, 2002: https://www.boost.org/doc/libs/1_31_0/libs/format/ https://www.boost.org/doc/libs/1_31_0/libs/format/
- 1ris 4y agoAnd outstreams where not that bad, aswell. Sure, the operator overloading looks a bit rough. But that's IMHO a pragmatic choice if you want to offer customisation points and didn't have variadic functions yet. They where introduced only in c++11.
- tialaramex 4y agoC++ did have variadic functions because it inherited them from C. What it didn't inherit from C was a way to write variadic functions with variadic types, so that had to be home grown.
- 1ris 4y agoDo you mean this feature [0]? I'm not aware of any differences in c and c++ about this. Can you get a type of a argument in C? How? At compile time, or at runtime? Both sound very un-C-like to me. cppreference is usually excellent documentation but it doesn't mention something like this. I don't considers this to be "proper" variadic arguments, because a functions argument has to have a type. and these, as far as I'm aware of don't have one. This is about a powerfull as passing a void**. This is essentially memcopying multiple differently typed into a char* buffer and then passing that buffer. You can than correctly copies them back you have pretty much the same behaviour. Both methodss obviously lacks important aspects of the language abstraction of a function parameter and i don't what that feature can bring to the table that the previous techniques don't. [0] https://en.cppreference.com/w/cpp/utility/variadic https://en.cppreference.com/w/cpp/utility/variadic
- kevin_thibedeau 4y ago> Can you get a type of a argument in C? You can get it indirectly using _Generic().
- 1ris 4y agoSorry my bad. Yes, it works for proper function arguments. Does this work for variadic arguments? Parent seems to suggest, but i'm not aware of any mechanism for this.
- tialaramex 4y agoSure, a hypothetical C++ 11 equivalent would e.g. probably not be able to do the trick where we reject bogus formats at compile time, which is something programmers want and which Rust only gets to do by making this a fancy macro whereas C++ 23 is doing it in the actual library code.
- otherjason 4y agofmtlib (https://github.com/fmtlib/fmt https://github.com/fmtlib/fmt), a C++11 formatting library that was the basis for C++20 std::format, is able to do this.
- tialaramex 4y agofmtlib does not, in fact, do this on C++ 11 because as explained it doesn't have enough constant evaluation. The fmtlib code uses a C-style macro to try to handle format errors at compile time, which detects whether it has enough consteval and no-ops if it does not. On a modern C++ with enough consteval it does exactly what you'd expect it to do, but on older compilers it does nothing. The result is that fmtlib on an older compiler gets you Exceptions, at runtime, for a format that was invalid at compile time, and if you upgrade the compiler it magically switches to compile time errors. Edited to add quote from fmtlib docs: "Compile-time checks are enabled by default on compilers that support C++20 consteval. On older compilers you can use the FMT_STRING macro defined in fmt/format.h instead. It requires C++14 and is a no-op in C++11."