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

C++17中如何实现指定模板:函数模板返回类型为第二模板参数

嘿,刚好C++17的特性完美解决这个需求,而且完全符合你要把F和V作为前两个模板参数的要求。咱们直接上代码,再一步步解释:

C++17 实现方案

核心思路是用std::invoke_result_t(C++17替代std::result_of的工具)自动推导可调用对象F的返回类型,然后把容器类型V作为第二个模板参数,默认值设为std::vector搭配F的返回类型。这样你既可以直接用默认的std::vector,也能随时替换成其他容器类型:

#include <functional>
#include <vector>
#include <list>
#include <array>
#include <iostream>

// 模板参数顺序:F(可调用对象类型)、V(容器类型,默认是std::vector<F的返回类型>)
// 用std::invoke_result_t自动获取F的返回类型,作为容器V的元素类型
template<typename F, typename V = std::vector<std::invoke_result_t<F>>>
V generate_container(F&& func) {
    V container;
    // 针对固定大小容器(如std::array)做适配处理
    if constexpr (std::is_same_v<V, std::array<std::invoke_result_t<F>, 1>>) {
        container[0] = std::forward<F>(func)();
    } else {
        container.emplace_back(std::forward<F>(func)());
    }
    return container;
}

// 测试示例
int main() {
    // 1. 默认使用std::vector,自动推导返回类型为int
    auto int_vec = generate_container([](){ return 42; });
    std::cout << "Vector value: " << int_vec[0] << "\n";

    // 2. 替换容器为std::list,元素类型自动匹配F的返回类型(std::string)
    auto str_list = generate_container([](){ return "Hello C++17!"; }, std::list<std::string>{});
    std::cout << "List value: " << *str_list.begin() << "\n";

    // 3. 替换为std::array(需要显式指定大小,元素类型自动匹配)
    auto int_arr = generate_container([](){ return 99; }, std::array<int, 1>{});
    std::cout << "Array value: " << int_arr[0] << "\n";

    return 0;
}

关键细节解释:

  • std::invoke_result_t:这是C++17引入的特性,比旧的std::result_of更直观——你只需要传入可调用对象类型F,它就能直接给出调用F()后的返回类型,不需要像std::result_of那样写std::result_of_t<F()>这种冗余语法。
  • 模板默认参数:我们把V的默认值设为std::vector<std::invoke_result_t<F>>,这样当用户只传F时,自动使用std::vector存储F的返回值;如果需要替换容器,只需要显式指定V的类型即可。
  • 兼容性处理:对于std::array这种固定大小的特殊容器,用C++17的if constexpr做针对性逻辑,避免编译错误,保证不同容器类型都能正常工作。

如果你的场景需要更复杂的容器初始化逻辑(比如传入初始大小、分配器等),还可以给函数添加额外参数传递这些信息,比如:

template<typename F, typename V>
V generate_container(F&& func, const V& prototype) {
    V container = prototype;
    // 自定义初始化逻辑
    container.emplace_back(std::forward<F>(func)());
    return container;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 08:49:07