MST

星途 面试题库

面试题:C++ 模板参数const与类型推导

考虑以下代码片段:template <typename T> void foo(T param) {},template <typename T> void bar(const T& param) {}。当我们调用foo(10)和bar(10)时,T的类型推导有何不同?如果传递的是一个const对象,例如const int num = 10; 分别调用foo(num)和bar(num),T的类型推导又会怎样?这种类型推导差异在模板参数使用const时有什么重要影响?
10.6万 热度难度
编程语言C++

知识考点

AI 面试

面试题答案

一键面试
  1. 调用foo(10)
    • T被推导为int。因为foo的参数param是值传递,编译器会忽略传递值的顶层const(如果有的话),10int类型,所以T推导为int
  2. 调用bar(10)
    • T被推导为intbar的参数paramconst T&,这里10是右值int类型,T被推导为int,然后param成为const int&类型,即对一个临时的const int对象的引用。
  3. 调用foo(num)
    • T被推导为int。同样因为foo是值传递,编译器忽略num的顶层constnumconst int类型,但传递给foo时,T仍然推导为intparam会是int类型的副本,丢弃了const属性。
  4. 调用bar(num)
    • T被推导为intbar的参数是const T&numconst intT推导为intparam成为const int&,即对num这个const int对象的引用。
  5. 这种类型推导差异在模板参数使用const时的重要影响
    • 值传递:在值传递的模板参数(如foo)中,顶层const会被忽略,这意味着模板函数内部不能修改传入的const对象,但函数会得到一个非const的副本。这在性能上可能有影响,因为会创建副本,并且丢失了对象可能原本具有的const语义。
    • 引用传递:在引用传递的模板参数(如bar)中,const是模板参数类型的一部分。这使得模板函数可以接受const和非const对象,并且能够保持对象的const属性,避免意外修改对象,同时也避免了不必要的副本创建,提高了效率。如果需要在模板函数中保证对象的常量性并且避免副本开销,使用const T&作为参数是更好的选择。