Skip to content

Question: locale treated differently by fmt and std::cout #3460

Description

@mcharneyamp

Pretty sure this is me being stupid; not a bug. Please see example here:

https://godbolt.org/z/rasnKzfae

When I uncomment line 22, I get what I want: no commas in hex number.

When I comment out line 22, I get commas in my hex numbers which is not what anyone would want.

What's the right way to do not get commas in hex numbers when using fmt and overloaded ostream operators?

Seems like std::out does not "see" the locale in the way fmt does. Is this because std::cout is constructed before main() sets std::locale::global(std::locale("en_US.UTF-8"));?

Thank you for your help. Apologies if this is a stupid question.

#include <cstdint>
#include <locale>
#include <ostream>
#include <iostream>
#include <iomanip>
#include <fmt/core.h>
#include <fmt/ostream.h>

class Foo {
public:
    Foo() = default;
    explicit Foo(std::uint64_t value) : contents(value) {}
    Foo(const Foo& other) : contents(other.contents) {}
    std::uint64_t value() const { return contents; }
    friend std::ostream& operator<<(std::ostream& os, const Foo& addr);
    std::uint64_t contents{0};
};

template <> struct fmt::formatter<Foo> : ostream_formatter {};
std::ostream& operator<<(std::ostream& os, const Foo& addr) {
    auto old_locale = os.getloc();
    os.imbue(std::locale("C"));  // line 22. comment this out and we get commas in hex number
    auto flags = os.setf(std::ios::hex, std::ios::basefield);
    os << addr.value();
    os.setf(flags);
    os.imbue(old_locale);
    return os;
}

int main(int argc, char** argv) {
    std::locale::global(std::locale("en_US.UTF-8"));
    Foo x(0xABCDEF00F);
    std::cout << "std cout: " << x << "\n";
    fmt::print("fmt     : {}\n", x);
}

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions