Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support to Approx for comparison with constructible types #652

Closed
jbcoe opened this issue May 4, 2016 · 9 comments
Closed

Add support to Approx for comparison with constructible types #652

jbcoe opened this issue May 4, 2016 · 9 comments

Comments

@jbcoe
Copy link
Contributor

jbcoe commented May 4, 2016

Approx is proving very useful to me. It would be more useful still if comparison between strong typedefs and Approx could be made to work without explicit conversions.


class Volatility {
  double underlying_;
 public:  
  explicit Volatility(double u) : underlying_(u) {}
  explicit operator double() const { return underlying_; }
}

auto v = Volatility(0.3);

REQUIRE(v == Approx(0.3)); // does not compile
REQUIRE(static_cast<double>(v) == Approx(0.3)); // compiles but I'd like to avoid verbosity

I'd be happy to do the work for this.

@nabijaczleweli
Copy link
Contributor

But Approx already supports constructible types...

@jbcoe
Copy link
Contributor Author

jbcoe commented May 4, 2016

I'll review my example and see if I can reproduce the problem I had.

@jbcoe
Copy link
Contributor Author

jbcoe commented May 4, 2016

The issue is with explicitly constructible types (example now updated to make this clear).

I'd like Catch's Approx to do the conversion for me.

@lightmare
Copy link
Contributor

I'd like Catch's Approx to do the conversion for me.

Then don't define the conversion operator explicit. The whole point of that keyword is to prevent the compiler from doing this conversion "for you".

@jbcoe
Copy link
Contributor Author

jbcoe commented May 5, 2016

The conversion operator is explicit because volatility is a strong typedef and I do not want implicit conversions because they can lead to nasty bugs (mixing volatilities and rates will give me wrong numbers).

Defining X::operator bool () as explicit does not stop implicit conversions in if(X). I think that comparison with Approx is a similar case and would like the conversion to be (safely) inferred.

I don't need Catch to solve this problem. I can define operator == etc for my strong typedefs if the Catch authors/maintainers don't think that allowing comparison with explicitly convertible types is desirable.

@lightmare
Copy link
Contributor

lightmare commented May 5, 2016

The conversion operator is explicit because volatility is a strong typedef and I do not want implicit conversions because they can lead to nasty bugs (mixing volatilities and rates will give me wrong numbers).

Makes sense.

Defining X::operator bool () as explicit does not stop implicit conversions in if(X). I think that comparison with Approx is a similar case and would like the conversion to be (safely) inferred.

That's evaluation in boolean context, which allows explicit conversion. See Contextual conversions

I don't need Catch to solve this problem. I can define operator == etc for my strong typedefs if the Catch authors/maintainers don't think that allowing comparison with explicitly convertible types is desirable.

I think I'm finally starting to understand. So you're asking for something like:

template<typename T> bool operator==(T const& lhs, Approx const& rhs)
{
  return rhs == static_cast<double>(lhs);
}
// etc.

@jbcoe
Copy link
Contributor Author

jbcoe commented May 5, 2016

That's right. I would add an enable_if to protect people from nasty compile errors.

Does this belong in Catch or should I implement it myself?

@lightmare
Copy link
Contributor

Only missing an update to approved.*.txt SelfTest output

@horenmar
Copy link
Member

@lightmare It will probably be missing for a while, until we figure out how to properly work with C++11 specific tests and features in approval tests.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants