为流运算符返回代理 class 时解包参数
Unpacking parameters when returning a proxy class for stream operator
我正在尝试使用流运算符实现以下行为:
std::cout << print(42, "foo", 'c', 2.0);
这是stream operator proxy的实现class:
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);
}
我正在尝试使用流运算符实现以下行为:
std::cout << print(42, "foo", 'c', 2.0);
这是stream operator proxy的实现class:
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);
}