c++ - 返回流运算符的代理类时解包参数
问题描述
我正在尝试使用流运算符实现以下行为:
std::cout << print(42, "foo", 'c', 2.0);
这是流操作符代理类的实现:
template <typename T>
class StreamProxy {
std::function<std::ostream &(std::ostream &, T)> m_func;
T m_arg;
public:
StreamProxy(std::function<std::ostream &(std::ostream &, T)> f, T arg)
: m_func(f), m_arg(arg) {}
inline void do_op(std::ostream &str) const { m_func(str, m_arg); }
};
template <typename T>
inline std::ostream &operator<<(std::ostream &os, StreamProxy<T> const &m) {
if (!os.good()) return os;
m.do_op(os);
return os;
}
template <typename T>
class Print : public StreamProxy<T const &> {
inline static std::ostream &call(std::ostream &os, T const &v) {
os << v;
return os;
}
public:
inline Print(T const &v) : StreamProxy<T const &>(call, v) {}
};
到目前为止,我只得到了基本案例,我正在努力解压参数:
template <typename T>
inline auto print(T const &v) {
return Print<T>(v);
}
template <typename T, typename... Args>
inline auto print(T const &v, Args &&... args) {
// NOTE: As pointed out by Davis Herring, the usage of stream operator here doesn't make sense.
return print(v) << print(args...); // This will fail!
}
如何使用参数包来实现?下面的错误消息似乎颇具误导性。
/home/me/Projects/ostr/include/ostr.hpp:62: error: no match for ‘operator<<’ (operand types are ‘Print<char [14]>’ and ‘Print<int>’)
return print(v) << print(args...);
~~~~~~~~~^~~~~~~~~~~~~~~~~
解决方案
在我看来,您使问题过于复杂,并且您将可变参数解包放置在错误的位置(在流不可用的情况下使用流运算符)。
在我看来,捕获 lambda 函数中的参数并使用std::ostream
.
我的意思是……如下
#include <iostream>
#include <functional>
struct foo
{
std::function<std::ostream & (std::ostream &)> l;
template <typename ... As>
foo (As && ... as)
: l{[&as...](std::ostream & os) -> std::ostream &
{ return ((os << std::forward<As>(as)), ...); }}
{ }
};
std::ostream & operator<< (std::ostream &os, foo const & f)
{ return os.good() ? f.l(os) : os; }
template <typename ... As>
foo print (As &&... as)
{ return { std::forward<As>(as)... }; }
int main ()
{
std::cout << print(42, "foo", 'c', 2.0);
}
推荐阅读
- r - 如何在叠加散点图中显示最佳拟合回归曲线和相应的 R^2?
- mysql-connector - 为什么 Hive Metastore 主机无法加载 mysql 连接器?
- youtrack - 创建指向 YouTrack 中现有问题的(子任务)链接
- vba - 对象尝试将一个单元格连接到上面的单元格时出现必需的错误
- javascript - 带有分子的 Node JS 微服务
- php - 将语言索引放入 URL 多语言 CodeIgniter 站点
- javascript - 当字段依赖于其他字段值时,如何添加不同的 yup 验证。if else-if else 验证
- r - 将 ggplot2 地图旋转到任意角度
- apache-spark - Spark Structured Streaming - 性能优化
- flutter - 如何使用用户名和密码文本字段获取令牌响应?飞镖/颤振