为什么编译器不能(或不)推断出static_cast的类型参数?

时间:2016-07-01 23:30:34

标签: c++ templates c++11 template-deduction

我有一些(遗留)代码,如下所示:

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
}

这是非常古老的代码,我意识到这是一种可怕的方式来进行这种正在发生的那种向下转换。但这让我很好奇:为什么我不能这样写呢?

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

当然它对编译器来说是明确的,它看起来像是函数中的普通模板参数推导。为什么不在这里进行类型演绎?

1 个答案:

答案 0 :(得分:3)

静态演员是危险的。在这种情况下,对void的强制转换必须使用完全相同的类型。

隐式typimg允许代码更改不直接与强制转换相邻,以使两个强制转换生成未定义的行为。

你可以制作符合你想要的代码,但不应该这样做。

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)};
}

现在auto_static_cast的行为与您希望static_cast的行为类似。