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_vvariable template instead of justfalseis needed for old versions of the compilers that doesn't implement the new rules according to CWG2518.Examples (the versions are inclusive):
falseeven in the current latest version.