'C++/doctest throws compiler warning when using namespaces
I am using the C++ doctest framework for unit testing and stumbled upon an issue.
Whenever I try using the CHECK_EQ() macro for objects not in the general namespace I get compiler error messages.
This compiles fine (godbolt)
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include <doctest.h>
struct Foo {
int i;
};
bool operator==(const Foo& lhs, const Foo& rhs) { return lhs.i == rhs.i; }
TEST_CASE("Foo") {
const auto f0 = Foo{};
const auto f1 = Foo{};
CHECK(f0 == f1);
CHECK_EQ(f0, f1);
}
But moving the struct inside a namespace breaks the compilation (godbolt)
#define DOCTEST_CONFIG_IMPLEMENT_WITH_MAIN
#include <doctest.h>
namespace internal {
struct Bar {
int i;
};
} // namespace internal
bool operator==(const internal::Bar& lhs, const internal::Bar& rhs) {
return lhs.i == rhs.i;
}
TEST_CASE("internal::Bar") {
const auto b0 = internal::Bar{};
const auto b1 = internal::Bar{};
CHECK(b0 == b1);
CHECK_EQ(b0, b1); // breaks code
}
The lengthy error messages:
In file included from <source>:3:
/opt/compiler-explorer/libs/doctest/trunk/doctest/doctest.h: In instantiation of 'bool doctest::detail::eq(const L&, const R&) [with L = internal::Bar; R = internal::Bar]':
/opt/compiler-explorer/libs/doctest/trunk/doctest/doctest.h:1485:5: required from 'bool doctest::detail::RelationalComparator<0, L, R>::operator()(const L&, const R&) const [with L = internal::Bar; R = internal::Bar]'
/opt/compiler-explorer/libs/doctest/trunk/doctest/doctest.h:1502:65: required from 'bool doctest::detail::ResultBuilder::binary_assert(const L&, const R&) [with int comparison = 0; L = internal::Bar; R = internal::Bar]'
<source>:19:3: required from here
/opt/compiler-explorer/libs/doctest/trunk/doctest/doctest.h:1292:5: error: no match for 'operator==' (operand types are 'const internal::Bar' and 'const internal::Bar')
1292 | DOCTEST_RELATIONAL_OP(eq, ==)
| ^
In file included from <source>:3:
/opt/compiler-explorer/libs/doctest/trunk/doctest/doctest.h:3583:6: note: candidate: 'bool doctest::operator==(const doctest::String&, const doctest::String&)'
3583 | bool operator==(const String& lhs, const String& rhs) { return lhs.compare(rhs) == 0; }
| ^~~~~~~~
/opt/compiler-explorer/libs/doctest/trunk/doctest/doctest.h:3583:31: note: no known conversion for argument 1 from 'const internal::Bar' to 'const doctest::String&'
3583 | bool operator==(const String& lhs, const String& rhs) { return lhs.compare(rhs) == 0; }
| ~~~~~~~~~~~~~~^~~
/opt/compiler-explorer/libs/doctest/trunk/doctest/doctest.h:3765:6: note: candidate: 'bool doctest::operator==(double, const doctest::Approx&)'
3765 | bool operator==(double lhs, const Approx& rhs) {
| ^~~~~~~~
/opt/compiler-explorer/libs/doctest/trunk/doctest/doctest.h:3765:24: note: no known conversion for argument 1 from 'const internal::Bar' to 'double'
3765 | bool operator==(double lhs, const Approx& rhs) {
| ~~~~~~~^~~
/opt/compiler-explorer/libs/doctest/trunk/doctest/doctest.h:3770:6: note: candidate: 'bool doctest::operator==(const doctest::Approx&, double)'
3770 | bool operator==(const Approx& lhs, double rhs) { return operator==(rhs, lhs); }
| ^~~~~~~~
/opt/compiler-explorer/libs/doctest/trunk/doctest/doctest.h:3770:31: note: no known conversion for argument 1 from 'const internal::Bar' to 'const doctest::Approx&'
3770 | bool operator==(const Approx& lhs, double rhs) { return operator==(rhs, lhs); }
Solution 1:[1]
This is an issue with doctest, see github-issue.
The workaround is to move the comparison operator into the same namespace, e.g.
namespace internal {
bool operator==(const Bar& lhs, const Bar& rhs) {
return lhs.i == rhs.i;
}
}
Don't quite know how to handle the case if the arguments are defined in different namespaces...
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | jack |
