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

C++11可变参数模板参数类型推导失败问题排查与解决

C++11下可变参数模板函数适配元组的实现问题

C++14可行方案

在C++14中可直接用std::apply实现将元组参数传递给函数的功能,示例代码如下:

#include <tuple>
template <typename T, typename U> void my_func(T &&t, U &&u) {}
int main(int argc, char *argv[argc]) {
  std::tuple<int, float> my_tuple;
  std::apply([](auto &&... args) { my_func(args...); }, my_tuple);
  return 0;
}

自行实现C++11方案的编译失败问题

尝试自行实现C++11下的适配逻辑,但调用u.apply(f)时出现类型推导失败的编译错误,完整尝试代码如下:

#include <iostream>
#include <tuple>

using namespace std;

template <typename... T>
struct parameter_pack : public parameter_pack<T>... {
    parameter_pack(const T&... t) : parameter_pack<T>(t)... {}

    // C++11 尝试的版本
    template <template <typename...> class Func>
    void apply(Func<T...> f) {
        f(parameter_pack<T>::h...);
    }
    // C++14 可行版本
    // template <typename Func>
    // void apply(Func f) {
    //     f(parameter_pack<T>::h...);
    // }

    // 更新:可行的C++11方案
    //void apply(void (*f)(const T&...)) {
    //    f(parameter_pack<T>::h...);
    //}
};

template <typename H>
struct parameter_pack<H> {
    parameter_pack(const H& h) : h(h) {}
    const H& h;
};

template <typename... T>
parameter_pack<T...> make_parameter_pack(const T&... t) {
    return parameter_pack<T...>(t...);
}

// 测试用重载函数f
template <typename H>
void f(const H& h) {
    std::cout << h << std::endl;
}

template <typename H, typename... T>
void f(const H& h, const T&... t) {
    f(h);
    f(t...);
}

int main() {
    auto u = make_parameter_pack(1, 1.1, "hello");
    std::cout << std::endl;
    // C++11 调用失败
    u.apply(f); // 编译器报错

    // C++14 可行调用方式
    // auto lambda = [&](const auto&... args) {
    //    f(args...);
    // };
    // u.apply(lambda);
}

编译器报错信息

<source>:49:7: error: no matching member function for call to 'apply'
   49 |     u.apply(f);
      |     ~~^~~~~
<source>:12:10: note: candidate template ignored: couldn't infer template argument 'Func'
   12 |     void apply(Func<T...> f) {
      |          ^
1 error generated.
Compiler returned: 1

类型推导失败的原因

尝试的C++11版本中,apply的模板参数是template <typename...> class Func,这要求传入的参数是模板类的实例,但f是重载的函数模板,并非模板类。编译器无法从函数模板f推导出对应的模板类参数Func,因此匹配失败。

可行的C++11解决方案

使用函数指针作为apply的参数(代码中已标记为更新的解决方案):

void apply(void (*f)(const T&...)) {
    f(parameter_pack<T>::h...);
}

该方案可行的原因是:当调用u.apply(f)时,编译器会根据parameter_pack的模板参数int, double, const char*,自动推导出匹配的f重载版本,生成对应的函数指针类型void(*)(const int&, const double&, const char* const&),与apply的参数类型完全匹配,因此可以正常编译运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 22:10:04