Fixes disagreement between operator<<
available for SFINAE and actually usable
#1405
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Originally I reported a bug, 1403 about how user code provides an insertion overload (an overload for
operator<<
) for anstd
type in the global namespace, however, the code fails to compile in Clang at the point Catch tries to use it, atReusableStringStream::operator<<
. This happens because the SFINAE tests for insertion availability happen afterusing ::operator<<
, thus the global overload is available, which activates theReusable
..., but when actually attempted to use them atReusableStringStream::operator<<
they are not available because:using ::operator<<
at that pointCatch
there has been one overload foroperator<<(std::ostream &, SourceLineInfo const &)
that makes the global overloads not available.This is not a strict bug because the user is providing an overload for types in
std
in the global namespace, which is not "the same namespace" as indicated in the Catch documentation.However, adding to the
std
namespace overloads ofoperator<<
are undefined behavior, and thus the only other choice for a user who wants to allow catch to stream-insertstd
types would be to put the overloads forstd
types intoCatch
, which then are inconvenient to use from the global namespace or the user namespaces. It seems the code tries to useoperator<<
global overloads, which works in GCC and perhaps other compilers that have broken two-phase lookup, but does not work in Clang which does it correctly in this case.With the fix presented, users will now be able to provide inserters in either the same namespace as their types (this does not change) or the global namespace, and Catch2 would be able to consistently test for insertion and use the given insertion operations.
The fix is simple, to hoist the
using ::operator<<
directive to right after introducing an overload intoCatch
namespace, which is the point at which the global overloads become non-available.I am thankful to Github user @mpark for his help elucidating ADL.
GitHub Issues
1403
#Closes 1403