Suppose I have a simple Duration
class:
class Duration
{
int seconds;
public:
Duration(int t_seconds) : seconds(t_seconds) { }
};
int main()
{
Duration t(30);
t = 60;
}
And I decide that I don't like being able to implicitly convert from int
to Duration
. I can make the constructor explicit
:
class Duration
{
int seconds;
public:
explicit Duration(int t_seconds) : seconds(t_seconds) { }
};
int main()
{
Duration t(30); // This is fine, conversion is explicit
t = 60; // Doesn't compile: implicit conversion no longer present for operator=
}
But what if I don't want to immediately break all calling code that's implicitly converting to Duration
? What I would like to have is something like:
class Duration
{
int seconds;
public:
[[deprecated]]
Duration(int t_seconds) : seconds(t_seconds) { }
explicit Duration(int t_seconds) : seconds(t_seconds) { }
};
int main()
{
Duration t(30); // Compiles, no warnings, uses explicit constructor
t = 60; // Compiles but emits a deprecation warning because it uses implicit conversion
}
This would allow existing code to compile while identifying any places that currently rely on implicit conversion, so they can either be rewritten to use explicit conversion if it's intended or rewritten to have correct behavior if not.
However this is impossible because I can't overload Duration::Duration(int)
with Duration::Duration(int)
.
Is there a way to achieve something like this effect short of "Make the conversion explicit, accept that calling code won't compile until you've written the appropriate changes"?
It is implicit conversion when a smaller data type is converted into a larger data type or derived class into a base class. On the other hand, the conversion in the opposite direction is known as explicit conversion. It needs a cast operator to convert higher data type into a smaller data type.
implicit casting doesn't require a casting operator. Explicit type casting is performed by the programmer. In this type casting programmer tells compiler to type cast one data type to another data type using type casting operator.
Implicit Conversions There is no special syntax for this type of conversion, this is the safest type of casting. No data is lost, for example, when converting from smaller to larger integral types or derived classes to base classes.
"Something that is implicit is expressed in an indirect way." "If a quality or element is implicit in something, it is involved in it or is shown by it;" Explicit. "Something that is explicit is expressed or shown clearly and openly, without any attempt to hide anything"
You can turn Duration(int t_seconds)
into a template function that can accept an int
and set it to deprecated.
#include<concepts>
class Duration {
int seconds;
public:
template<std::same_as<int> T>
[[deprecated("uses implicit conversion")]]
Duration(T t_seconds) : Duration(t_seconds) { }
explicit Duration(int t_seconds) : seconds(t_seconds) { }
};
If you allow t = 0.6
, just change the same_as
to convertible_to
.
Demo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With