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

如何解决模板成员函数存入std::function数组/元组的编译错误?

修复模板成员函数存入std::array/std::tuple的编译错误

以下针对两种存储场景的编译错误,分别说明原因并给出修复方案:

一、std::arraystd::function场景的错误修复

错误原因

编译器无法直接将模板成员函数f<I>转换为std::function<unsigned int()>,核心问题有两点:

  • 成员函数必须依赖对象的this指针才能调用,直接传递函数名无法绑定当前对象;
  • 即便enable_if限制了重载,编译器仍无法自动推导函数类型以消除歧义。

修复方案

可以通过两种方式明确绑定当前对象并消除类型歧义:

方式1:使用lambda捕获this

#include <array>
#include <functional>
#include <type_traits>
#include <utility>

template <bool X>
struct A {
  template <unsigned int I, bool activate = X, class = std::enable_if_t<activate>>
  unsigned int f() { return 0; }

  template <unsigned int... I>
  auto collect_allf_impl(std::integer_sequence<unsigned int, I...>) {
    return std::array<std::function<unsigned int()>, 3>{
        [this](){ return this->f<I>(); }...
    };
  }

  auto collect_allf() {
    return collect_allf_impl(std::make_integer_sequence<unsigned int, 3>{});
  }
};

int main()
{
  A<true> x{};
  auto all = x.collect_allf();
}

方式2:使用std::bind绑定当前对象

#include <array>
#include <functional>
#include <type_traits>
#include <utility>

template <bool X>
struct A {
  template <unsigned int I, bool activate = X, class = std::enable_if_t<activate>>
  unsigned int f() { return 0; }

  template <unsigned int... I>
  auto collect_allf_impl(std::integer_sequence<unsigned int, I...>) {
    return std::array<std::function<unsigned int()>, 3>{
        std::bind(&A::f<I>, this)...
    };
  }

  auto collect_allf() {
    return collect_allf_impl(std::make_integer_sequence<unsigned int, 3>{});
  }
};

int main()
{
  A<true> x{};
  auto all = x.collect_allf();
}

二、std::tuple场景的错误修复

错误原因

直接写f<I>时,编译器无法将其解析为明确的成员函数指针类型——即便enable_if限制了重载,仍需要显式指定包含类类型的成员函数地址。

修复方案

显式取成员函数的地址,明确指定为&A<X>::f<I>:

#include <array>
#include <functional>
#include <type_traits>
#include <tuple>
#include <utility>

template <bool X>
struct A {
  template <unsigned int I, bool activate = X, class = std::enable_if_t<activate>>
  unsigned int f() { return 0; }

  template <unsigned int... I>
  auto collect_allf_impl(std::integer_sequence<unsigned int, I...>) {
    return std::make_tuple(&A<X>::f<I>...);
  }

  auto collect_allf() {
    return collect_allf_impl(std::make_integer_sequence<unsigned int, 3>{});
  }
};

int main()
{
  A<true> x{};
  auto all = x.collect_allf();
}

如果需要存储可直接调用的对象而非成员函数指针,也可以用lambda捕获this存入tuple:

#include <array>
#include <functional>
#include <type_traits>
#include <tuple>
#include <utility>

template <bool X>
struct A {
  template <unsigned int I, bool activate = X, class = std::enable_if_t<activate>>
  unsigned int f() { return 0; }

  template <unsigned int... I>
  auto collect_allf_impl(std::integer_sequence<unsigned int, I...>) {
    return std::make_tuple([this](){ return this->f<I>(); }...);
  }

  auto collect_allf() {
    return collect_allf_impl(std::make_integer_sequence<unsigned int, 3>{});
  }
};

int main()
{
  A<true> x{};
  auto all = x.collect_allf();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 20:34:53