Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How do I preserve inter-string null characters in std::format string

In an attempt to refactor this code:

static const auto opf_str = [&]() {
    std::string result;
    for(auto& e : extension_list) {
        result.append(StringUtils::ToUpperCase(e.substr(1)) + " file (*"s + e + ")\0*"s + e + "\0"s);
    }
    result += "All Files (*.*)\0*.*\0\0"s;
    return result;
}();

I replaced the std::string::operator+ joins with std::format:

static const auto opf_str = [&]() {
    std::string result;
    for(auto e : extension_list) {
        result.append(std::format("{0} file (*{1})\0*{1}\0", StringUtils::ToUpperCase(e.substr(1)), e));
    }
    result += "All Files (*.*)\0*.*\0\0"s;
    return result;
}();

But the internal null characters (which are required for how OPENFILENAME works) are being stripped in the std::format version.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Changing the format string to an actual std::string causes a compiler error because the string isn’t a compile-time constant.

>Solution :

std::string as argument doesn’t work, but at least std::string_view should be fine. There is no issue with having it even as the result of a constant expression if it is referencing only static objects:

std::format("{0} file (*{1})\0*{1}\0"sv, StringUtils::ToUpperCase(e.substr(1)), e)

Looking a the current draft specification of std::basic_format_string it is indeed impossible to use a std::string as format string to std::format, even if its construction is a constant expression. As an alternative it is of course always possible to use std::vformat instead, which doesn’t perform the compile-time checks. (It is in the end not really surprising since the consteval construction of the std::basic_format_string would need to copy the string contents, but can’t rely on storing the result in dynamic memory.)

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading