英文:
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 <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';
}
答案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 <>
struct std::formatter<enum_t>: formatter<unsigned> {
auto format(enum_t v, format_context& ctx) const {
return formatter<unsigned>::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...
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论