I want to write a function string_to_float
with template parameter T
such that string_to_float = std::stof
, string_to_float = std::stod
and string_to_float = std::stold
, when T = float
, T = double
and T = long double
, respectively. My attempt was the following:
template<typename T>
T string_to_float(std::string const& s, std::size_t* pos = nullptr)
{
static_assert(std::is_same_v<T, float> || std::is_same_v<T, double> || std::is_same_v<T, long double>,
"T is not a built-in floating point type");
if constexpr (std::is_same_v<T, float>)
return std::stof(s, pos);
if constexpr (std::is_same_v<T, double>)
return std::stod(s, pos);
if constexpr (std::is_same_v<T, long double>)
return std::stold(s, pos);
return T{};
}
However, I worry about the return
statement. While the static assertion will already fail in that case, I don't want to produce an additional misleading compiler error when T
is not default constructible.
I also want to make sure that the code produced by an invocation of string_to_float
is really exactly the same as if I had used std::stof
, std::stod
or std::stold
directly (assuming, of course, that T = float
, T = double
or T = long double
).
This is why I didn't remove the last if-clause checking for T
being equal to long double
and simply returned std::stold(s, pos);
in the last line. On the other hand, at compile time the it is already clear if T = float
or T = double
and in that case, there would be a return
before the return
in the last line; so the compiler might ignore that return
anyways.
I've also looked at the attribute specifier sequences and hoped that there is some kind of [[unreachable]]
attribute so that the compiler really knows that the code below this line will never be reached.
Then, don't include that last
return T{};
. It's not ever going to be used anyway.Example:
The
always_false_v
variable template instead of justfalse
is needed for old versions of the compilers that doesn't implement the new rules according to CWG2518.Examples (the versions are inclusive):
false
even in the current latest version.