c – 可以将static_cast引用到相同类型的引入运行时开销吗?

我有一个结构模板,它有两种类型(T和S),在某种程度上使用一个static_cast从一种类型转换为另一种类型.通常情况下,T和S是相同的类型.

一个简化的设置示例:

template <typename T,typename S = T>
struct foo
{
  void bar(T val)
  {
    /* ... */
    some_other_function(static_cast<S>(val));
    /* ... */
  }
};

在S与T相同的情况下,static_cast是否或可以引入额外的开销,还是一个总是被忽略的空操作?

如果它引入了开销,是否有一个简单的模板元编程技巧来执行static_cast只有在需要的时候,还是需要创建一个部分专业化来处理T == S的情况?如果可能,我宁愿避免整个foo模板的部分专业化.

解决方法

是的,它可以.

这是一个例子:

struct A {
  A( A const& ) {
    std::cout << "expensive copy\n";
  }
};

template<typename T>
void noop( T const& ) {}
template <typename T,typename S = T>
void bar(T val)
{
  noop(static_cast<S>(val));
}
template <typename T>
void bar2(T val)
{
  noop(val);
}
int main() {
  std::cout << "start\n";
  A a;
  std::cout << "bar2\n";
  bar2(a); // one expensive copy
  std::cout << "bar\n";
  bar(a); // two expensive copies
  std::cout << "done";
}

基本上,static_cast可以引发一个复制构造函数调用.

对于某些类型(如int),复制构造函数基本上是空闲的,编译器可以消除它.

对于其他类型,它不能.在这种情况下,copy elision也不合法:如果您的副本构造函数具有副作用或编译器无法证明它没有副作用(如果复制构造函数不常见),它将被调用.

相关文章

对象的传值与返回说起函数,就不免要谈谈函数的参数和返回值...
从实现装饰者模式中思考C++指针和引用的选择最近在看...
关于vtordisp知多少?我相信不少人看到这篇文章,多半是来自...
那些陌生的C++关键字学过程序语言的人相信对关键字并...
命令行下的树形打印最近在处理代码分析问题时,需要将代码的...
虚函数与虚继承寻踪封装、继承、多态是面向对象语言的三大特...