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

使用std::any实现的double与int乘法函数编译失败求助

问题原因

你的代码无法正常执行乘法逻辑(实际是运行时抛出异常,并非编译错误),核心问题如下:

  1. 类型未被处理:乘法测试中你用2.5f(float类型)初始化std::any c,但GenericBinaryOperation的分支仅覆盖了int、double和std::string类型,完全没有针对float的判断逻辑,因此会进入else分支抛出invalid_argument异常。
  2. 次要逻辑错误:字符串拼接部分错误传入了add而非定义好的concatenate,虽不影响乘法逻辑,但会导致字符串拼接复用加法lambda。
解决方法

针对核心问题,有两种可行思路:

思路一:统一使用double类型

将2.5f改为2.5(double字面量),让std::any c存储double类型,匹配已有的double+int分支:

std::any c = 2.5;

思路二:扩展类型处理逻辑

在GenericBinaryOperation中增加对float类型的支持,可通过统一转换为double来复用现有逻辑,避免重复编写分支:

struct GenericBinaryOperation {
    template <typename Func>
    std::any operator()(const std::any& lhs, const std::any& rhs, Func&& func) const {
        // 统一将数值类型转换为double
        auto get_double = [](const std::any& val) -> double {
            if (val.type() == typeid(int)) return std::any_cast<int>(val);
            if (val.type() == typeid(double)) return std::any_cast<double>(val);
            if (val.type() == typeid(float)) return std::any_cast<float>(val);
            throw std::invalid_argument("Unsupported numeric type");
        };

        // 判断是否为数值类型组合
        bool is_lhs_numeric = lhs.type() == typeid(int) || lhs.type() == typeid(double) || lhs.type() == typeid(float);
        bool is_rhs_numeric = rhs.type() == typeid(int) || rhs.type() == typeid(double) || rhs.type() == typeid(float);
        if (is_lhs_numeric && is_rhs_numeric) {
            return func(get_double(lhs), get_double(rhs));
        }
        // 处理字符串拼接
        else if (lhs.type() == typeid(std::string) && rhs.type() == typeid(std::string)) {
            return func(std::any_cast<std::string>(lhs), std::any_cast<std::string>(rhs));
        } else {
            throw std::invalid_argument("Unsupported or mismatched types");
        }
    }
};

这种方式更灵活,能兼容更多数值类型组合。

修正后的完整代码
#include <iostream>
#include <any>
#include <stdexcept>
#include <typeinfo>

struct GenericBinaryOperation {
    template <typename Func>
    std::any operator()(const std::any& lhs, const std::any& rhs, Func&& func) const {
        // 统一将数值类型转换为double
        auto get_double = [](const std::any& val) -> double {
            if (val.type() == typeid(int)) return std::any_cast<int>(val);
            if (val.type() == typeid(double)) return std::any_cast<double>(val);
            if (val.type() == typeid(float)) return std::any_cast<float>(val);
            throw std::invalid_argument("Unsupported numeric type");
        };

        bool is_lhs_numeric = lhs.type() == typeid(int) || lhs.type() == typeid(double) || lhs.type() == typeid(float);
        bool is_rhs_numeric = rhs.type() == typeid(int) || rhs.type() == typeid(double) || rhs.type() == typeid(float);
        if (is_lhs_numeric && is_rhs_numeric) {
            return func(get_double(lhs), get_double(rhs));
        }
        else if (lhs.type() == typeid(std::string) && rhs.type() == typeid(std::string)) {
            return func(std::any_cast<std::string>(lhs), std::any_cast<std::string>(rhs));
        } else {
            throw std::invalid_argument("Unsupported or mismatched types");
        }
    }
};

int main() {
    GenericBinaryOperation operation;

    // Integer and double addition
    std::any a = 5;
    std::any b = 3.5;
    auto add = [](auto x, auto y) { return x + y; };
    std::cout << "Add (int + double): " << std::any_cast<double>(operation(a, b, add)) << std::endl;

    // Float and integer multiplication
    std::any c = 2.5f;
    std::any d = 4;
    auto multiply = [](auto x, auto y) { return x * y; };
    std::cout << "Multiply (float * int): " << std::any_cast<double>(operation(c, d, multiply)) << std::endl;

    // String concatenation
    std::any e = std::string("Hello, ");
    std::any f = std::string("World!");
    auto concatenate = [](auto x, auto y) { return x + y; };
    std::cout << "Concatenate (string + string): " << std::any_cast<std::string>(operation(e, f, concatenate)) << std::endl;

    // Example of mismatched types causing an exception
    try {
        std::any g = 42;
        std::any h = std::string("Forty-Two");
        operation(g, h, add); // This will throw an exception due to type mismatch
    } catch (const std::invalid_argument& ex) {
        std::cerr << "Error: " << ex.what() << std::endl;
    }

    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 06:05:00