0

introduced variable templates so I can do:

template <typename T>
const auto PI = std::acos(static_cast<T>(-1));

Now, when using this variable can the type be deduced? For example:

const auto TWO_PI = 2.0F * PI;

Here I would expect PI<float> it seems like the compiler should be able to deduce that. Why won't the compiler select this for me?

Praetorian
  • 106,671
  • 19
  • 240
  • 328
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • 6
    Why do you expect float deduction ? – Jarod42 Feb 23 '18 at 21:30
  • 4
    No idea why you believe PI should be float. – SergeyA Feb 23 '18 at 21:35
  • @Jarod42 Cause it's multiplied by a `float`? – Jonathan Mee Feb 23 '18 at 21:46
  • @SergeyA Cause it's multiplied by a `float`? – Jonathan Mee Feb 23 '18 at 21:46
  • 4
    So the compiler should randomly look around at subexpressions and pick *something* if possible? How's that useful behavior? – Praetorian Feb 23 '18 at 21:57
  • and for `template std::size_t Fact();` you expect in `5 * Fact()` `N` is deduced as 5 ? :) – Jarod42 Feb 23 '18 at 21:57
  • @Jarod42 No an you're talking about a function, which *is* deduced by what's passed to it. – Jonathan Mee Feb 23 '18 at 22:02
  • 2
    Well, so what? Even if I take your line of thinking (I am still unsure how compiler is expected to deduce the type), still float could be multiplied by multiple different types. Why single out float? However, it is all bizarre. Alleged relationship between template argument of template variable and type of the variable is still beyond me. – SergeyA Feb 23 '18 at 22:07
  • @SergeyA So I think a good example of this would be: `min(1L, 0.0F)` this is ambiguous. You'd have to cast to the same type, or explicitly specify the `min` template you are using. So for example: `min(static_cast(1L), 0.0F)` It makes me sad that you don't see how this directly corresponds to something like `1L * PI * 0.0F`. It's ambiguous in the *exact* same way. You'd need to cast so it was clear which version of `PI` you were using or explicitly specify the template. So for example: `static_cast(1L) * PI * 0.0F` – Jonathan Mee Feb 24 '18 at 16:49

1 Answers1

0

No, it's not possible.*


*There is an ugly alternative, but I'd advise against using it:

template <typename T> const auto pi = std::acos(static_cast<T>(-1));

struct auto_pi_t {} auto_pi;

template <typename T> auto operator+(T a, auto_pi_t)
{return a + pi<std::conditional_t<std::is_floating_point_v<T>, T, double>>;}
template <typename T> auto operator+(auto_pi_t, T a)
{return pi<std::conditional_t<std::is_floating_point_v<T>, T, double>> + a;}
// For similar overloads for all plausible operators.
Community
  • 1
  • 1
HolyBlackCat
  • 78,603
  • 9
  • 131
  • 207