When I try to compile the ApprovalTests.cpp project with Clang, I receive this error message:
In file included from /Users/arh/code/ApprovalTests.cpp/src/ApprovalTests_Catch2_Tests/CombinationTests.cpp:8:
/Users/arh/code/ApprovalTests.cpp/src/ApprovalTests/../ApprovalTests/CombinationApprovals.h:102:58: error: call to function 'operator<<' that is neither visible in the template definition nor found by argument-dependent lookup
s << ") => " << result << '\n';
Clang is actually correct here, and the problem is that gcc and msvc accept incorrect code. The situation is described in detail at http://clang.llvm.org/compatibility.html#dep_lookup and the second example describes exactly the case in ApprovalTests.
There are two obvious ways to make the problem go away quickly:
- Put the
operator<< overload in
CombinationTests.cpp inside the
std namespace, so that it can be found by ADL in the
verifyAllCombinations function template. Unfortunately this is illegal, as we're only allowed to put full specializations in to the
- Predeclare the
operator<< overload before including the
This Godbolt example contains a minimal example:
I'm probably going outside the scope of this Issue now, but I believe a better approach would be to provide a customization point that allows users to provide custom string conversions for their own types, or for types that do not easily support a stream insertion operator. Sometimes third-party types do provide a stream insertion operator, but its output isn't acceptable for some reason. In those cases, it's helpful to have a separate mechanism for stringifying the type.
The Catch2 library has a nice mechanism for this:
The Boost unit test library does it too:
Neither of those implementations could be described as 'trivial', but I think that some form of customization point that goes beyond requiring an
operator<< overload would be advantageous for ApprovalTests.cpp.
Whilst looking in to this, I found a useful reference on best practices for providing customization points: