0

I have some (legacy) code that looks like:

void castFoo(string type, void* foo) {
  FooA* foo_a = NULL;
  FooB* foo_b = NULL;

  if (type == "A") {
    foo_a = static_cast<FooA*>(foo);
  } else {
    foo_b = static_cast<FooB*>(foo);
  }

  // now do things with one of the two foo's
}

This is very old code and I realize that this is a terrible way to do the sort of downcasting that's happening here. But it made me curious: why can't I write it like this?

  if (type == "A") {
    foo_a = static_cast(foo);
  } else {
    foo_b = static_cast(foo);
  }

Surely it's unambiguous to the compiler, and it looks like a normal template argument deduction in a function to me. Why is type deduction not done here?

Patrick Collins
  • 10,306
  • 5
  • 30
  • 69
  • 3
    What, in your opinion, should be the type of `decltype(static_cast(foo))` or `decltype(static_cast(foo))`? If it's not the same as the meaning when that expression appears in statements like you showed, isn't that kind of horrible for generic programming? – Chris Beck Jul 01 '16 at 23:34
  • `std::string var; var = static_cast(thing);` there's _three_ `operator=` that the cast could cast to. – Mooing Duck Jul 01 '16 at 23:40
  • What should the type of `static_cast(foo)` deduce to? – M.M Jul 01 '16 at 23:44
  • "*Why is type deduction not done here?*" Among the many other reasons people have given, I would add the practical matter that you should not be typing the words `static_cast` often enough to warrant such a language feature. – Nicol Bolas Jul 02 '16 at 04:52

1 Answers1

3

Static cast is dangerous. In this case, casting to/from void must go to the exact same type.

Implicit typimg would allow code changes not directly adjacent to the casts to make the two casts generate undefined behaviour.

You can make code that does what you want, as ill advised as it is.

template<class V>
struct implicit_static_cast_t{
  V v;
  template<class T>
  operator T()&&{
    return static_cast<T>(std::forward<V>(v));
  }
};

template<class In>
implicit_static_cast_t<In>
auto_static_cast(In&& in){
  return {std::forward<In>(in)};
}

Now auto_static_cast behaves like you want static_cast behaves like.

Yakk - Adam Nevraumont
  • 262,606
  • 27
  • 330
  • 524