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

如何修正代码使cookie_name_t仅使用移动构造与赋值(编译失败)

问题分析与代码修正

当你删除cookie_name的拷贝构造函数和拷贝赋值运算符后,包含它的std::tuple<cookie_name_t, cookie_value_t, cookie_options_t>会自动失去拷贝能力,原代码编译错误集中在insert_or_update函数的两处逻辑:

  1. cookies_.emplace_back(cookie):函数参数里的cookie是右值引用,但在函数内部它是左值,调用emplace_back时会尝试拷贝tuple,而tuple中的cookie_name_t已禁用拷贝,导致编译失败。
  2. 需要确保所有涉及tuple的操作都优先使用移动语义,避免隐式拷贝触发错误。

具体修正步骤

  1. 修复insert_or_update中的emplace_back调用
    将传递cookie改为std::move(cookie),强制触发tuple的移动构造:
if (value == cookies_.end())
    cookies_.emplace_back(std::move(cookie));
  1. 优化cookie_name的operator()返回值(推荐)
    原operator()返回value_type的拷贝,改成返回const引用可避免不必要的拷贝,同时不影响功能:
const value_type& operator()() const noexcept { return value_; }
  1. 可选:添加右值引用版本的cookie成员函数
    如果需要支持直接传入cookie_name_t的右值,可新增重载函数,利用移动语义提升性能:
void cookie(cookie_name_t&& cookie, cookie_value_t const &value) { 
    insert_or_update(std::make_tuple(std::move(cookie), value(), std::string{})); 
}

完整修正代码

class cookie_name final
{
public:
    using value_type = std::string;

    cookie_name() = delete;

    cookie_name(value_type const &value) noexcept(std::is_nothrow_copy_constructible_v<value_type>) : value_{value} {};

    cookie_name(value_type &&value) noexcept(std::is_nothrow_move_constructible_v<value_type>) : value_{std::move(value)} {};

    // 禁用拷贝构造和拷贝赋值
    cookie_name(cookie_name const &) = delete;            
    cookie_name &operator=(cookie_name const &) = delete; 

    // 默认移动构造和移动赋值
    cookie_name(cookie_name &&) noexcept(std::is_nothrow_move_constructible_v<value_type>) = default;         
    cookie_name &operator=(cookie_name &&) noexcept(std::is_nothrow_move_assignable_v<value_type>) = default; 

    // 返回const引用避免不必要拷贝
    const value_type& operator()() const noexcept { return value_; }

    bool operator==(cookie_name const &rhs) const noexcept { return this->value_ == rhs.value_; }
    bool operator!=(cookie_name const &rhs) const noexcept { return !(this->value_ == rhs.value_); }

private:
    value_type value_;
};
using cookie_name_t = cookie_name;
using cookie_value_t = cookie_value; // 假设cookie_value类已正确定义
using cookie_options_t = std::string; // 假设原代码中cookie_options_t为std::string

class cookies final
{
public:
    using cookie_t = std::tuple<cookie_name_t, cookie_value_t, cookie_options_t>;

private:
    using raw_cookie_t = std::vector<cookie_t>;

public:
    cookies() = default;

    void cookie(cookie_name_t const &cookie, cookie_value_t const &value) { 
        insert_or_update(std::make_tuple(cookie(), value(), std::string{})); 
    }
    // 可选:支持右值引用的重载
    void cookie(cookie_name_t&& cookie, cookie_value_t const &value) { 
        insert_or_update(std::make_tuple(std::move(cookie), value(), std::string{})); 
    }
    auto write_cookies() const; // 假设该函数已正确实现

private:
    void insert_or_update(cookie_t &&cookie);

private:
    raw_cookie_t cookies_;
};

void cookies::insert_or_update(cookie_t &&cookie)
{
    auto value{std::find_if(cookies_.begin(), cookies_.end(), [&cookie](auto &iter)
                            { return std::get<0>(iter)() == std::get<0>(cookie)(); })};
    if (value == cookies_.end())
        cookies_.emplace_back(std::move(cookie)); // 触发移动构造
    else
        *value = std::move(cookie); // 触发移动赋值
}

关键说明

  • 禁用拷贝后,所有涉及cookie_name_t的容器操作必须通过std::move转换为右值引用,触发移动构造/赋值。
  • std::tuple的移动操作会自动调用成员的移动逻辑,只要cookie_name_t、cookie_value_t、cookie_options_t支持移动,tuple的移动就能正常工作。
  • 调整operator()返回const引用可减少字符串拷贝开销,提升代码性能。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 15:31:14