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

带右值引用的可变参数模板运算符>>重载技术问询

如何为模板类型实现接收右值引用的>>运算符?

首先还原你的场景和问题:

我原本有这样的代码定义:

template<typename ... TL> struct TemplatedType { };
template<typename ... TL> std::istream& operator>>(std::istream& is, TemplatedType<TL ...> & sp) { // do stuff return is; }

使用示例:

std::istringstream iss("I'd like some pancakes, please");
TemplatedType<int> a;
iss >> a;

这段代码能正常运行,但我希望把模板参数以右值引用的形式接收,也就是定义类似template<typename ... TL> std::istream& operator...的运算符,请问该怎么实现?


其实你要的就是为TemplatedType实现接收右值引用参数的operator>>重载,直接修改参数类型就能搞定,下面分两种情况给你说明:

1. 单独定义右值引用版本的运算符

直接把原来的左值引用参数改成右值引用,模板参数包的写法保持不变即可:

template<typename ... TL> 
std::istream& operator>>(std::istream& is, TemplatedType<TL ...> && sp) { 
    // 这里可以针对右值对象做特殊处理,比如移动内部资源
    // 也可以复用原有逻辑,比如:
    // is >> /* 操作sp的成员变量 */;
    return is; 
}

这样之后,编译器会根据你传入的对象值类别自动匹配对应版本:

// 传入左值,调用原左值引用版本
TemplatedType<int> a;
iss >> a;
// 传入右值,调用新的右值引用版本
iss >> TemplatedType<int>{};

2. 用转发引用兼容左值和右值

如果不想写两个重载,也可以用转发引用(Forwarding Reference)写一个通用版本,同时兼容左值和右值。不过需要加个限制,避免这个运算符被其他无关类型误匹配:

#include <type_traits>

// C++20及以上版本的写法
template<typename T> 
std::enable_if_t<std::is_specialization_v<T, TemplatedType>, std::istream&>
operator>>(std::istream& is, T&& sp) { 
    // 使用std::forward保持原始值类别,左值还是左值,右值还是右值
    // do stuff with std::forward<T>(sp)
    return is; 
}

如果是C++17及更早版本,std::is_specialization_v还不存在,你可以自己实现一个判断模板特化的 trait:

template<typename T, template<typename...> class Template>
struct is_specialization : std::false_type {};

template<template<typename...> class Template, typename... Args>
struct is_specialization<Template<Args...>, Template> : std::true_type {};

template<typename T, template<typename...> class Template>
constexpr bool is_specialization_v = is_specialization<T, Template>::value;

// 用自定义trait实现通用运算符
template<typename T> 
std::enable_if_t<is_specialization_v<T, TemplatedType>, std::istream&>
operator>>(std::istream& is, T&& sp) { 
    // 同样用std::forward处理值类别
    return is; 
}

这样不管你传左值还是右值,这个运算符都能正确匹配,而且不会干扰其他类型的operator>>逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:30:36