Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Broken support for printing abstract classes with ostream adapter #2439

Closed
PiotrZSL opened this issue Jul 28, 2021 · 5 comments
Closed

Broken support for printing abstract classes with ostream adapter #2439

PiotrZSL opened this issue Jul 28, 2021 · 5 comments

Comments

@PiotrZSL
Copy link

PiotrZSL commented Jul 28, 2021

ENV: GCC 10 + FMT 8.0.1 (master) + FMT_COMPILE + fmt::format_to + reference to abstract class as argument.
Abstract class got friend operator <<.

Result: Compilation fails.
Issue looks to be caused by std::numeric_limits.
Fails with: limits:317:7: error: invalid abstract return type ‘'.

Workaround:
format.h (ignored is_fast_float for classes)

 567 template<typename T, bool = std::is_class<T>::value>
 568 struct Workaround : std::false_type
 569 {
 570 };
 571
 572 template<typename T>
 573 struct Workaround<T, false> : bool_constant<std::numeric_limits<T>::is_iec559 && sizeof(T) <= sizeof(double)>
 574 {
 575
 576 };
 577
 578 template <typename T>
 579 using is_fast_float = Workaround<T>;

ostream.h (added & to std::declval to create reference to type instead of rvalue).

 75 template <typename T, typename Char> class is_streamable {
 76  private:
 77   template <typename U>
 78   static bool_constant<!std::is_same<decltype(std::declval<test_stream<Char>&>()
 79                                               << std::declval<U&>()),
 80                                      void_t<>>::value>
@vitaut
Copy link
Contributor

vitaut commented Jul 28, 2021

Please provide a repro.

@PiotrZSL
Copy link
Author

PiotrZSL commented Jul 28, 2021

Example:

#include <fmt/format.h>
#include <fmt/compile.h>
#include <fmt/ostream.h>

struct Abstract
{
    virtual ~Abstract() = default;
    virtual void print() = 0;
    friend std::ostream& operator<<(std::ostream& out, Abstract&);
};


void testFail(Abstract& value)
{
    fmt::memory_buffer buf;
    fmt::format_to(std::back_inserter(buf), FMT_COMPILE("{}"), value);
}

Link: https://godbolt.org/z/KxzGEdhT7

GCC10 - Fails in ostream.h and format.h
GCC11 - Fails only in ostream.h due to lack of "const Abstract&" in "operator <<".

@vitaut
Copy link
Contributor

vitaut commented Jul 30, 2021

Could you submit a PR by any chance?

@PiotrZSL
Copy link
Author

PiotrZSL commented Jul 30, 2021

Could you submit a PR by any chance?

Ok, I understand you mean pull request, probably I could...

@vitaut
Copy link
Contributor

vitaut commented Sep 2, 2021

Fixed in ee0659f. With this change your example compiles (with a missing const added). Thanks for reporting.

@vitaut vitaut closed this as completed Sep 2, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants