2

How can I have a function like this

template<typename TValue>
TValue GridSnap(TValue Value, TValue Grid)

That resolves template type from only the first parameter like this

GridSnap(ADouble, AFloat)  => TValue should resolve to double
GridSnap(AFloat,  ADouble) => TValue should resolve to float
GridSnap(AFloat,  AInt)    => TValue should resolve to float

basically I don't want to manually cast the second argument, it would be nice if it could just do implicit cast base on the first parameter.

M.kazem Akhgary
  • 18,645
  • 8
  • 57
  • 118
  • The type of both the function parameters(`Value` and `Grid`) is `TValue` so the passed arguments `ADouble` and `AFloat` must be of the same type otherwise you'll get error saying conflicting types deduced. – Jason Sep 03 '22 at 04:52
  • @JasonLiam that's what I'm trying to avoid without using explicit casts everywhere. – M.kazem Akhgary Sep 03 '22 at 05:02
  • [Related](https://stackoverflow.com/a/66945877) – Patrick Roberts Sep 03 '22 at 05:03
  • @M.kazemAkhgary I see. So the [answer](https://stackoverflow.com/a/73589722/12002570) below should solve that. – Jason Sep 03 '22 at 05:04

2 Answers2

3

What you want to do is to have the template parameter of the second function parameter to be in a non-deduced context. You can do this using std::type_identity like

template <typename TValue>
TValue GridSnap(TValue Value, std::type_identity_t<TValue> Grid)

If you can't use C++20, then you can just write your own type_identity and type_identity_t like

template <typename T>
struct type_identity 
{
    using type = T;
};

template <typename T>
using type_identity_t = typename type_identity<T>::type;
NathanOliver
  • 171,901
  • 28
  • 288
  • 402
1

@NathanOliver solution worked nicely, But I also found this solution

TValue GridSnapAuto(TValue Value, decltype(Value) Grid)
M.kazem Akhgary
  • 18,645
  • 8
  • 57
  • 118