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

C++模板函数传递数组与同类型元素时类型推导冲突的解决

解决C++模板参数推导冲突问题

你的问题确实是模板参数推导冲突:调用logSearch(asd, 3)时,第一个参数asd是int[10]类型,编译器会推导模板参数T为int[10];但第二个参数3是int类型,编译器又会推导T为int。两种推导结果矛盾,导致编译报错。

同时你的两个模板函数还有其他隐含问题:

  • binSearch的第四个参数T x,如果T是数组类型(比如int[10]),这个参数会变成数组类型,无法接收int值;
  • logSearch中sizeof(A)/sizeof(A[0])得到的是数组元素总数,但二分查找的右边界应该是元素总数-1(因为数组索引从0开始),否则会访问越界;
  • binSearch没找到元素时返回0,会和第一个元素的索引混淆,应该返回无效值(比如-1)。

修正后的代码

binSearch.hh 文件内容

#include <cstddef> // 用于size_t类型

template<typename T>
int binSearch(const T* A, int u, int v, T x) {
    if (u > v) return -1; // 没找到返回-1,避免和有效索引混淆
    int m = u + (v - u) / 2; // 用此方式计算中间值,防止u+v溢出

    if (A[m] > x) return binSearch(A, u, m - 1, x);
    if (A[m] < x) return binSearch(A, m + 1, v, x);
    else return m;
}

// 针对C风格数组的logSearch,用模板参数自动捕获数组大小
template<typename T, size_t N>
int logSearch(const T (&A)[N], T x) {
    return binSearch(A, 0, static_cast<int>(N) - 1, x); // 右边界设为N-1
}

测试代码

#include <iostream>
#include "..\binSearch.hh"

int main() {
    int asd[] = {0,1,2,3,4,5,6,7,8,9};

    std::cout << logSearch(asd, 3); // 输出3,正确找到目标元素索引

    return 0;
}

方案解释

  • binSearch改用const T*接收数组,数组会自动退化为指针,此时T是元素类型(比如int),第四个参数T x类型完全匹配;
  • logSearch用两个模板参数:T是元素类型,N是数组大小(由编译器自动推导),彻底避免类型冲突;
  • 修正中间值计算方式,避免u+v溢出(当u和v为较大int值时);
  • 没找到元素时返回-1,逻辑更严谨。

扩展方案(支持STL容器)

如果想让logSearch同时支持C风格数组和STL容器(如std::vector),可以添加重载版本:

template<typename Container, typename T>
int logSearch(const Container& A, T x) {
    return binSearch(A.data(), 0, static_cast<int>(A.size()) - 1, x);
}

此版本要求容器提供data()和size()方法,STL容器均满足该条件。

内容的提问来源于stack exchange,提问作者Iván

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 17:26:06