Skip to content

examples/parameterized.cpp: overload of format_test_parameter is ineffective #683

@asiz

Description

@asiz

The intended behaviour is documented in the comments:

  // Modifying test names when using alternative syntax
  // When using the alternative syntax, the test names are extended based on the
  // test parameters (to ensure uniqueness). Here, for simple built-in types,
  // the parameter value is printed, while other types are simply enumerated.
  // Without the `format_test_parameter` overload above, the test names for the
  // test below would be:
  //   "parameterized test names (42, int)"
  //   "parameterized test names (true, bool)"
  //   "parameterized test names (3rd parameter, std::complex<double>)"
  // However, since the overload for std::complex is available, the third test name becomes:
  //   "parameterized test names (1.5+2i, std::complex<double>)"
 "parameterized test names"_test = []<class TArg>([[maybe_unused]] TArg arg) {
    expect(true);
  } | std::tuple{42, true, std::complex{1.5, 2.0}};

However, modifying the test with expect(false), the report is

Running test "parameterized test names (3rd parameter, std::complex<double>)"... FAILED
in: parameterized.cpp:90 - test condition:  [false]

That is, the complex value 1.5+2i is not printed. As far as I checked (I am using g++ -std=c++23/26), the behaviour is the same since the commit e131611f that first introduced the example. The critical piece of code is the intended overload:

namespace boost::inline ext::ut {

namespace {
template <std::floating_point F>
std::string format_test_parameter(const std::complex<F>& arg,
                                  [[maybe_unused]] const int counter) {
  std::ostringstream oss;
  oss << arg.real() << '+' << arg.imag() << 'i';
  return oss.str();
}
}  // namespace

}  // namespace boost::inline ext::ut

The overload is ineffective because it is not accessible at the point of usage (inside ut.hpp). I could reproduce the intended result in a few ways:

  1. By changing the overload to a full template specialization, and removing the anonymous namespace.
  2. *By moving the overload to the std namespace.
  3. By using a custom type or template in a custom namespace, and including the overload there.

Option 1 works because we are no longer overloading, but specializing the already declared template.
Option 2* works because of ADL, but is illegal.
Option 3 works because of ADL, and is legal.

It seems the example should be fixed. Am I correct? What do you think?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions