boostorg / leaf

Lightweight Error Augmentation Framework

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

explicit conversion constructor called implicitly in result<T> -> result<U> conversion

strager opened this issue · comments

It looks like LEAF has a way to construct a result<U> from a result<T>. This is handy, but the conversion happens for explicit constructors, which I find surprising.

Here's an example:

#include <boost/leaf.hpp>
#include <string>
#include <vector>

boost::leaf::result<std::size_t> g() {
  return 42;
}

boost::leaf::result<std::vector<std::string>> f() {
  // Surprise! std::vector<std::string>::vector(std::size_t) is called.
  return g();
}

int main() {
  auto r = f();
  printf("vector contains %d strings\n", (int)r->size());
}

I expect the above example to fail to compile. std::vector<std::string>::vector(std::size_t) is an explicit constructor, so converting from a boost::leaf::result<std::size_t> to a boost::leaf::result<std::vector<std::string>> should fail.

If I use std::optional instead of boost::leaf::result everywhere in the example program, compilation fails, as expected:

test.cpp: In function ‘std::optional<std::vector<std::__cxx11::basic_string<char> > > f()’:
test.cpp:11:11: error: could not convert ‘g()’ from ‘optional<long unsigned int>’ to ‘optional<std::vector<std::__cxx11::basic_string<char> >>’
   11 |   return g();
      |          ~^~
      |           |
      |           optional<long unsigned int>

I like std::optional's behavior here. LEAF should not call an explicit constructor when converting result types.

I added a couple of unit tests, this is now fixed on develop. Currently Boost is undergoing a Beta release and merges to master are disallowed. Once the beta is released, I'll be able to merge and it'll be included in the 1.77 Boost release.

It may be a good time to report more issues if you find them. :)