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

实现简易std::any时赋值字符串字面量报错的原因及修复方法

错误原因解析
  • 第一个报错触发逻辑:传入字符串字面量"abc"时,完美转发模板的类型推导会将Tp推导为数组引用类型const char (&)[4],C++语法禁止对引用类型执行new操作,直接触发new cannot be applied to a reference type错误。
  • 转换目标char的来源:剥离引用层后,Tp对应的原生类型是长度为4的const char数组const char[4];对数组类型执行placement new时,编译器会尝试逐个构造数组元素,元素类型就是单个char。而数组作为实参传入构造逻辑时会自动退化为const char*指针,因此编译器提示无法将const char*转换为char。
  • 原实现的隐藏缺陷:没有记录存储对象的实际类型、没有调用存储对象的析构函数,即使绕过编译错误,也会存在内存泄漏、类型不匹配取值时的未定义行为。
修复方案

核心修复逻辑是在模板参数推导后,用std::decay_t对类型做退化处理:剥离引用、cv限定符,将数组类型转换为对应指针类型,将函数类型转换为函数指针,从根源避免拿到引用、数组等无法直接构造的类型。
补充类型擦除逻辑实现自动析构、类型安全校验后,可运行代码如下:

#include <iostream>
#include <type_traits>
#include <memory>
#include <typeinfo>

class TinyAny
{
    struct StorageBase {
        virtual ~StorageBase() = default;
    };

    template <typename T>
    struct Storage : StorageBase {
        T value;
        template <typename U>
        Storage(U&& v) : value(std::forward<U>(v)) {}
    };

    std::shared_ptr<StorageBase> data;
public:
    TinyAny() = default;

    template <typename Tp, typename T = std::decay_t<Tp>>
    TinyAny(Tp&& val) : data(std::make_shared<Storage<T>>(std::forward<Tp>(val))) {}

    template <typename Tp, typename T = std::decay_t<Tp>>
    TinyAny& operator=(Tp&& val)
    {
        data = std::make_shared<Storage<T>>(std::forward<Tp>(val));
        return *this;
    }

    template <typename Tp, typename T = std::decay_t<Tp>>
    Tp get()
    {
        auto* storage = dynamic_cast<Storage<T>*>(data.get());
        if (!storage) {
            throw std::bad_cast();
        }
        return storage->value;
    }
};

int main() {
    TinyAny var;
    var = "abc";
    std::cout << var.get<const char*>() << std::endl;

    var = 123;
    std::cout << var.get<int>() << std::endl;

    var = std::string("hello world");
    std::cout << var.get<std::string>() << std::endl;
    return 0;
}
  • 上述实现额外补了默认构造函数,支持先声明再赋值的使用方式;通过基类虚析构保证存储对象正确释放,dynamic_cast做类型校验避免非法类型转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 13:06:30