Custom formatter在clang和gcc中无法编译,但在MSVC中成功。

huangapple go评论71阅读模式
英文:

Custom formatter failed to compile in clang and gcc, but succeeded in MSVC

问题

以下代码在gcc 14 ([链接](https://wandbox.org/permlink/jscue0UvN9xgtzzj)) 和clang 17 ([链接](https://wandbox.org/permlink/NEmuU3Lnr1RtsGNR)) 中无法编译通过,但在MSVC 17.6.2中成功。gcc和clang报告了许多对我来说毫无意义的错误。错误消息过长,无法在此处发布。请参考链接获取详细信息。有人能帮我理解这里发生了什么吗?format库在gcc和clang中是相当新的。这可能是一个库实现的bug吗?

~~~
#include <format>
#include <iostream>

enum struct enum_t: unsigned {
    cat,
    dog
};

template <>
struct std::formatter<enum_t>: formatter<unsigned> {
    auto format(enum_t v, format_context& ctx) {
        return formatter<unsigned>::format(unsigned(v), ctx);
    }
};

int main() {
    std::cout << std::format("{}", enum_t::cat) << '\n';
}
~~~
英文:

Following code failed to compile in gcc 14 (link) and clang 17 (link), yet succeeded in MSVC 17.6.2. gcc and clang throw tons of errors that do not make sense to me. Error message is too lengthy to be posted here. Please refer to the links for details. Could someone help me understand what's going on here? The format library is quite new in gcc and clang. Could this be a library implementation bug?

#include &lt;format&gt;
#include &lt;iostream&gt;

enum struct enum_t: unsigned {
    cat,
    dog
};

template &lt;&gt;
struct std::formatter&lt;enum_t&gt;: formatter&lt;unsigned&gt; {
    auto format(enum_t v, format_context&amp; ctx) {
        return formatter&lt;unsigned&gt;::format(unsigned(v), ctx);
    }
};

int main() {
    std::cout &lt;&lt; std::format(&quot;{}&quot;, enum_t::cat) &lt;&lt; &#39;\n&#39;;
}

答案1

得分: 5

关于使用 libstdc++ 产生的错误:

根据_BasicFormatter_要求,必须能够在格式化程序特化类型的const限定对象上调用format

您的format成员函数没有const限定,因此无法在这种调用中使用它(它还隐藏了基类的format)。

您需要给成员函数加上const限定:

template <>
struct std::formatter<enum_t>: formatter<unsigned> {
    auto format(enum_t v, format_context& ctx) const {
        return formatter<unsigned>::format(unsigned(v), ctx);
    }
};

这个要求不是在C++20中,但是在当前的C++23草案中通过LWG 3636的解决而存在。我认为这应该是一个缺陷报告,因此如果您使用-std=c++20编译,它也应该适用。

我还不知道Clang和libc++对代码有什么问题。我会进行调查…

英文:

As far as the error produced with libstdc++ is concerned:

According to the BasicFormatter requirements, it must be possible to call format on a const-qualified object of the type of the formatter specialization.

Your format member function isn't const-qualified, so it can't be used in such a call (and it also hides the format from the base class).

You need to const-qualify the member function:

template &lt;&gt;
struct std::formatter&lt;enum_t&gt;: formatter&lt;unsigned&gt; {
    auto format(enum_t v, format_context&amp; ctx) const {
        return formatter&lt;unsigned&gt;::format(unsigned(v), ctx);
    }
};

This requirement isn't in C++20, but is in the current C++23 draft via resolution of LWG 3636. I think it is intended to be a defect report, so that it should also apply if you compile with -std=c++20.

I don't yet know what issue Clang with libc++ has with the code. I'll investigate...

huangapple
  • 本文由 发表于 2023年5月29日 19:32:33
  • 转载请务必保留本文链接:https://go.coder-hub.com/76356967.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定