0

My group maintains some legacy container classes, which stores both pointers and 32-bit integers. When they were written pointers were 32-bits but they're now 64-bits. We have two versions of every function, one for pointers and one for integers, which I'm trying to merge into one function using templates. How can I do this and make the compiler happy? A toy version of the problem is below.

void* mPtr = nullptr;

template<class T>
void Func(T t) {
  mPtr = reinterpret_cast<void*>(t);
}

template<class T>
T Func2() {
  if (typeid(T) == typeid(int))
    return static_cast<int>(reinterpret_cast<long long>(mPtr));
  else
    return static_cast<T>(mPtr);
}

class MyClass {};
int main() {
  MyClass someClass;
  Func(&someClass);
  MyClass* myClass = Func2<MyClass*>();
  int val = Func2<int>();
}

Please remember that this is just a toy problem and I'm only interested in answers here relating to whether it's possible to rewrite the body of Func2() so that this code compiles without error. I realize that it is possible to use template specialization here, for example, but that doesn't meet the criteria of the question. Thanks!

dromodel
  • 9,581
  • 12
  • 47
  • 65
  • Is your question essentially about how to write a template function where the return type depends on the template argument? – Lukas-T Oct 01 '19 at 17:20

1 Answers1

3

Use if constexpr (and fix all the typos in the code):

template<class T>
T Func2() {
  if constexpr (std::is_same_v<T, int>)
    return static_cast<int>(reinterpret_cast<long long>(mPtr));
  else
    return static_cast<T>(mPtr);
}

See also Difference between "if constexpr()" Vs "if()".

Max Langhof
  • 23,383
  • 5
  • 39
  • 72
  • Looks perfect! Although, sadly, this looks like C++17 functionality which our compiler version doesn't fully support (gcc 6.2.). Any tips for C++14? – dromodel Oct 01 '19 at 22:45
  • 1
    @dromodel You will have to make do with template specialization then, sorry. – Max Langhof Oct 02 '19 at 07:15