Wrong operator

1 day ago 3
ARTICLE AD BOX

I don't know why the overload selection is made as such, but thanks to @NathanOliver I found an explanation and a workaround:

The usage of the member function doesn't matter here.

The inline overload is always selected because it is preferred against the const & one, and then a compile error occurs because there is no suitable append() overload.

To force the use of the correct operator I added this version of append() to the Builder class:

template<typename T, typename = std::enable_if_t<std::is_class_v<T>>> Packet & append(T const & t) { return *this << t; }

Chnossos's user avatar

1 Comment

Where did the Packet type come from? Is that supposed to correspond to the Builder type in the question?

2026-03-03T03:12:58.187Z+00:00

To see "why" keep in mind that an auto parameter type is basically shorthand for a template, so your code is roughly equivalent to this:

Builder & append(int); Builder & append(double); template <class T> Builder & operator<<(T && t) { return append(t); } // [1] };

Since it calls append, T has to be either int, double, or some type that will implicitly convert to int or double. Since there's no conversion from X to int or double, it fails. We can make it work by adding a conversion from X to int:

struct X { friend Builder & operator<<(Builder & p, X const &) { return p << 42; } operator int() { return 1; } // conversion to `double` would work just as well. };

...or by adding an overload of append that takes an X:

struct X; struct Builder { Builder & append(int); Builder & append(double); Builder & append(X const &); // ... many other overloads Builder & operator<<(auto && t) { return append(t); } // [1] // ...

Either will work. In this situation, you can have both, but if you ended up with equal conversion sequences, you'd get an ambiguity and it wouldn't compile.

Jerry Coffin's user avatar

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Read Entire Article