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

如何编写泛型代码计算Eigen矩阵或类元组对象的大小?

通用计算类数组/元组/Eigen矩阵元素总数的泛型实现

你的问题出在第一个模板的约束不够严格:当传入Eigen矩阵时,编译器会尝试实例化std::tuple_size_v<std::decay_t<T>>,但Eigen类型没有std::tuple_size的特化,这会触发硬编译错误,而非SFINAE的替换失败,导致第二个重载根本没机会被选中。

C++20 简洁实现(推荐)

用requires约束明确限定第一个模板仅对支持std::tuple_size的类型生效:

#include <tuple>
#include <array>
#include <Eigen/Core>

// 匹配类数组/元组类型(std::tuple、std::array、std::pair等)
template <typename T>
constexpr auto size(const T&) requires requires { std::tuple_size_v<std::decay_t<T>>; }
{
    return std::tuple_size_v<std::decay_t<T>>;
}

// 匹配所有Eigen矩阵/向量类型
template <typename Derived>
constexpr auto size(const Eigen::MatrixBase<Derived>& mat)
{
    return mat.size();
}

// 可选:原生数组重载(std::tuple_size也支持原生数组,此重载更直观)
template <typename T, std::size_t N>
constexpr std::size_t size(const T (&)[N]) noexcept
{
    return N;
}

C++17 及更早版本兼容实现

用SFINAE结合void_t实现类型检测:

#include <tuple>
#include <array>
#include <type_traits>
#include <Eigen/Core>

// 检测类型是否支持std::tuple_size
template <typename T, typename = void>
struct has_tuple_size : std::false_type {};

template <typename T>
struct has_tuple_size<T, std::void_t<decltype(std::tuple_size_v<std::decay_t<T>>)>> : std::true_type {};

// 仅对支持std::tuple_size的类型启用
template <typename T>
constexpr std::enable_if_t<has_tuple_size<T>::value, std::size_t> size(const T&)
{
    return std::tuple_size_v<std::decay_t<T>>;
}

// Eigen矩阵专属重载
template <typename Derived>
constexpr std::size_t size(const Eigen::MatrixBase<Derived>& mat)
{
    return mat.size();
}

// 原生数组重载
template <typename T, std::size_t N>
constexpr std::size_t size(const T (&)[N]) noexcept
{
    return N;
}

效果验证

  • 传入std::tuple{1, 2, 3}返回3
  • 传入std::array<int, 5>{}返回5
  • 传入Eigen::MatrixXd(3, 4)返回12
  • 传入int[10]{}返回10

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 04:55:23