c++函数模版类型推导

C++函数模板类型推导方法

        对于c++的函数模版,可以处理通用的数据类型,特别是stl中针对容器和算法的一些处理,如果自己写某个过程,如果不借助类型推导还真不好处理。

        


#include <iostream>
#include <string>
#include <vector>
#include <functional>

template <typename T, typename P>
std::vector<T> Filter(const std::vector<T>& vec, P preb){
    std::vector<T> res;
    for(auto s: vec){
        if(preb(s)){
            res.push_back(s);
        }
    }

    return res;
}

int main(){
    std::string word = "apple";
    auto hasWord = [&word](const std::string &s)->bool{ return s.find(word) != std::string::npos; };
    std::vector<std::string> words = {"An apple", "orange", "green apple", "grape"};

    std::vector<std::string> res = Filter(words, hasWord);
    for(auto &s: res){
        std::cout<<s<<std::endl;
    }
    return 0;
}

      &nb

### C++ 模板函数的隐式类型推导规则 C++ 中模板函数的隐式类型推导是一种强大的机制,允许编译器自动推导模板参数的具体类型。以下是关于隐式类型推导的一些重要规则: #### 1. 基本类型匹配 当传递给模板函数的实际参数是一个基本数据类型的变量时,模板会尝试将其与形参进行精确匹配。如果实际参数是 `int` 类型,则模板中的 `T` 将被推导为 `int`。 ```cpp template<typename T> void myfunc(T param) { std::cout << "T is: " << typeid(T).name() << std::endl; } myfunc(42); // 输出:T 是 int[^1] ``` #### 2. 引用和常量修饰符的影响 对于带有引用或常量修饰符的模板参数,编译器会在推导过程中保留这些修饰符。例如,在调用 `myfunc(j)` 时,由于传入的是一个 `const int` 变量,因此模板参数 `T` 被推导为 `int`,而形参 `param` 的具体类型则是 `const int&`。 ```cpp const int j = 20; template<typename T> void myfunc(const T& param) {} myfunc(j); // T 推导为 int, param 类型为 const int& ``` #### 3. 数组退化为指针 当数组作为实参传递到模板函数中时,默认情况下会被退化为指向其第一个元素的指针。这意味着模板参数不会保持原始数组的形式。 ```cpp template<typename T> void myfunc(T param) {} int arr[5]; myfunc(arr); // T 被推导为 int*, 不再是 int[5][^2] ``` #### 4. 多个参数的情况 在涉及多个模板参数的情况下,每个参数都会独立地参与类型推导过程。然而需要注意的是,所有模板参数之间必须能够形成一致的关系才能成功完成推导。 ```cpp template<class T> void func(T a, T b){ a = b; // 编译器期望两个参数具有相同的类型 } ``` 上述代码片段表明只有当两者均为相同类型或者可以相互赋值转换的时候才可以通过编译测试。 #### 5. 自动类型转换的应用场景限制 尽管存在一些内置类型的隐式转换(如从较小整数类型向较大整数类型的提升),但在大多数情形下,这种行为并不适用于复杂的数据结构或是用户自定义类对象间的关系判定上。 --- ### 示例代码展示 下面通过一段综合性的例子来进一步说明以上提到的各种情况: ```cpp #include <iostream> #include <typeinfo> // 定义通用打印函数 template<typename T> void printType(const T& value) { std::cout << "Value type: " << typeid(value).name() << "\n"; std::cout << "Template parameter T: " << typeid(T).name() << "\n\n"; } int main(){ int i = 10; double d = 3.14; // 测试基础数值类型 printType(i); printType(d); // 测试带 cv-qualifiers 和 references 的情况 const int ci = 20; printType(ci); return 0; } ``` 此程序展示了不同类型输入如何影响最终所得到的结果以及它们各自对应的内部实现细节差异之处。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值