You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

传递地址时普通函数与函数模板的语法限制差异解析

问题解析:普通函数与函数模板的参数匹配差异

一、普通函数f传入指针报错的原因

普通函数f的参数被固定声明为const Widget&,这意味着它只能接受可以隐式转换为const Widget&的类型。当传入&arg[0]时,实参的类型是Widget*(指向Widget对象的指针),指针类型和引用类型之间不存在合法的隐式转换规则,编译器无法将Widget*绑定到const Widget&参数上,因此直接触发编译错误。

二、函数模板f2适配两种参数的原因

函数模板f2依靠C++的模板参数推导机制工作:编译器会根据传入的实参类型,自动推导模板参数T的具体类型,然后生成对应的实例化函数,不需要手动指定类型。这让模板函数能灵活适配多种不同的参数类型。

三、两种有效调用场景下的T类型

  • 调用f2(arg[0])时:
    实参arg[0]是Widget类型(vector的operator[]返回容器元素的引用),编译器推导T为Widget,生成的函数签名为void f2(const Widget& param),此时调用我们为Widget类自定义的operator<<,输出对象的属性内容。
  • 调用f2(&arg[0])时:
    实参是Widget*类型(指向第一个Widget对象的指针),编译器推导T为Widget*,生成的函数签名为void f2(Widget* const & param)(即指向Widget的const指针的引用)。此时打印param时,会调用C++标准库为指针类型提供的默认operator<<,输出指针的内存地址(如示例中的0x55feee619eb0)。

代码示例

#include <iostream>
#include <vector>

class Widget {
public:
    friend std::ostream &operator<<( std::ostream &output, const Widget &w ) { 
        output << "Attr : " << w.attr;
        return output;            
    }
private:
    int attr = 5;
};

void f(const Widget& param) {
  std::cout << param << std::endl;
}

template<typename T>
void f2(const T& param) {
  std::cout << param << std::endl;
}

int main() {
    std::vector<Widget> arg = {Widget()};
    if (!arg.empty()) {
        f(arg[0]);
        //f(&arg[0]);   <-- 此处会触发编译错误
        f2(arg[0]);
        f2(&arg[0]); // <-- 为何此处可正常运行?
    }
}

运行输出

Attr : 5
Attr : 5
0x55feee619eb0

内容的提问来源于stack exchange,提问作者RCal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 17:22:41