I have the following code, which doesn't compile with x86_64 GCC 13:
#include <iostream>
#include <stdfloat>
int main() {
std::cout << std::float128_t{1} << '\n';
}
This gives me the following error:
<source>: In function 'int main()':
<source>:5:15: error: ambiguous overload for 'operator<<' (operand types are 'std::ostream' {aka 'std::basic_ostream<char>'} and 'std::float128_t' {aka '_Float128'})
5 | std::cout << std::float128_t{1} << '\n';
| ~~~~~~~~~ ^~ ~~~~~~~~~~~~~
| | |
| | std::float128_t {aka _Float128}
| std::ostream {aka std::basic_ostream<char>}
The listed ambiguous overloads are:
operator<<(long)operator<<(unsigned long)operator<<(bool)- ...
Surprisingly, operator<<(float) and other floating point types aren't listed.
I've checked the compiler support page for C++23, and this feature should be supported:
| C++23 features | Paper(s) | libstdc++ | libc++ | MVSV STL |
|---|---|---|---|---|
| Standard names and library support for extended floating-point types |
P1467R9 | 13 | 19.37** |
See C++23 compiler support page
Am I misunderstanding something? Is cppreference wrong and extended floating-point types aren't fully supported yet?
How do I print a std::float128_t without third-party libraries?
operator<<(std::float128_t)is optionalNone of the
operator<<overloads for extended floating-point types from<stdfloat>are guaranteed to exist. Forstd::float128_tit is quite common that this isn't the case. On x86_64:long doubleis typically an 80-bit floating point type, andstd::float128_tis a quadruple precision IEEE-754 floating-point type.This means that
std::float128_thas a greater conversion rank1) thanlong double. As a result,operator<<(std::float128_t)is optional:- [ostream.formatted]/[ostream.inserters.arithmetic] §5
GCC isn't required to support it, and you should consider alternatives to
operator<<when printing extended floating point types.Alternatives
This solution currently works, and is guaranteed to work. The
std::formatterfor extended floating-point types is implemented usingstd::to_chars, which is required to support all arithmetic types.This solution doesn't work yet because libstdc++ doesn't implement the
<print>header yet. However, once it does, this will also work, becausestd::printlnalso usesstd::formatter.If
std::formatworks, why isoperator<<not supported?The proposal paper answers this question:
- P1467r9 §iostream
1) The conversion rank is greater because
std::float128_tcan represent more values thanlong double, see [conv.rank] §2.