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

如何编写仅接受两种支持[]运算符的C++模板函数?

C++限定模板函数仅适配两种支持[]运算符的类型

如果你需要让C模板函数只接受指定的两种支持[]运算符的类型,可以根据C版本选择不同的实现方式,以下是具体方案:

C++20及以上:使用Concepts(推荐)

C++20引入的Concepts可以像TypeScript的extends一样直观地限定模板参数类型,写法简洁且可读性强:

#include <string>
#include <vector>
#include <concepts>
#include <type_traits>

// 定义Concept,限定允许的类型为std::string或std::vector<int>(可按需修改)
template<typename T>
concept AllowedType = std::same_as<std::remove_cvref_t<T>, std::string> || 
                      std::same_as<std::remove_cvref_t<T>, std::vector<int>> ||
                      std::same_as<std::remove_cvref_t<T>, int[]>; // 支持原生int数组

// 应用Concept限定模板参数
template<AllowedType T>
auto func(T&& arg) {
    return arg[0];
}

// 测试示例
int main() {
    func(std::string("hello"));       // 合法:std::string符合要求
    func(std::vector<int>{1, 2, 3});  // 合法:std::vector<int>符合要求
    int arr[] = {4, 5, 6};
    func(arr);                        // 合法:原生int数组符合要求
    
    // func(std::vector<double>{1.1, 2.2}); // 编译错误:类型不在允许列表中
    // func(123);                          // 编译错误:int不支持[](或不在允许列表)
    return 0;
}

AllowedType概念明确指定了模板参数必须是std::string、std::vector<int>或原生int[],不符合条件的类型会在编译阶段直接报错,和TypeScript的类型检查逻辑一致。

C++20之前:使用SFINAE与类型特性(Type Trait)

如果需要兼容C11/C17,可以借助SFINAE机制结合自定义类型特性来实现类型限定:

#include <string>
#include <vector>
#include <type_traits>

// 自定义类型特性,默认标记为不允许的类型
template<typename T>
struct is_allowed_type : std::false_type {};

// 特化:允许std::string
template<>
struct is_allowed_type<std::string> : std::true_type {};

// 特化:允许std::vector<int>
template<>
struct is_allowed_type<std::vector<int>> : std::true_type {};

// 特化:允许任意长度的原生int数组
template<std::size_t N>
struct is_allowed_type<int[N]> : std::true_type {};

// 使用std::enable_if_t实现SFINAE,仅当类型符合要求时实例化模板
template<typename T, typename = std::enable_if_t<is_allowed_type<std::remove_cvref_t<T>>::value>>
auto func(T&& arg) {
    return arg[0];
}

// 测试示例
int main() {
    func(std::string("test"));
    func(std::vector<int>{10, 20});
    int arr[] = {100, 200};
    func(arr);
    
    // func(std::vector<float>{1.0f, 2.0f}); // 编译错误
    return 0;
}

这里通过is_allowed_type结构体标记允许的类型,再用std::enable_if_t在模板参数列表中做过滤——只有当类型特性为true时,模板才会被成功实例化,否则会因为SFINAE规则被编译器忽略,最终触发编译错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 12:37:18