1. 8
  1.  

  2. 2

    I’ve been really enjoying the compile-time checked format string thing in libfmt that this article refers to. There’s also a thing that lets you get the type of a tuple that captures all of the arguments that a format string expects, which is great for this kind of thing where you want to provide a set of values for the format string in one place and then the localised version of the format string elsewhere.

    1. 2

      I may be weird but I’m more of a fan of the templated version. Can the following not do something that the blog post code can? https://godbolt.org/z/xMYE3aTf6

      1. 2

        Here’s the reduced test case for you:

            constexpr const char *foo = "valid";
            checker<foo, 10>();
        

        Yours will fail here, but the expression-based version (fmt(foo, 10)) works. In this degenerate case it doesn’t matter too much, but if you want to put the strings in a constant array and refer to them via index then it does. You could replace the array with a template that is specialised for each integer value and evaluates to the string and then use that in the template but it would be a lot more verbose and things like iterating over all error messages would be harder. Having it as a value in the expression also makes localisation easier and potentially more efficient - you can remove the string from the final binary entirely and just preserve the array index, which you use to look up the format string for the current locale from the localisation database.

        1. 1

          Since std::string_view is invented, nobody needs to take C strings anymore, right? Problem solved?

          This piece of C++17 works in Clang and Msvc:

          #include <string_view>
          
          constexpr int constexpr_strcmp(std::string_view a, std::string_view b) {
              return (a.empty() || b.empty() || a[0] != b[0])
                  ? a[0] - b[0]
                  : constexpr_strcmp(a.substr(1), b.substr(1));
          }
          
          static_assert(constexpr_strcmp("right", "right") == 0); // ok
          static_assert(constexpr_strcmp("wrong", "right") == 0); // error
          

          Annoyingly, it fails to compile in Gcc for the wrong reason: __builtin_unreachable() is not a constant expression. I don’t know which compiler is right, but I’m sure such an implementation detail is not prescribed.

          Maybe it could be made to work in Gcc by making a custom string_view. That would even make it valid C++11!