我的C++ 17折叠类具有以下operator<<()
重载:
template <typename... Args>
ostream& operator <<(Args&&... args)
{
//Currently:
return (m_osCout << ... << args);
//What I need:
IF ANY OF THE parameters in args "was" of type, say TSeek,
which can be a manipulator function etc, then AFTER finishing
with the parameter pack, I would like to do some further operation
, for instance, restore the state of m_osCount
}
如上所述,我可能需要什么吗?对于设置一些方向的任何部分回应将不胜感激...
尽管我提出这个问题似乎是在要求一个自动化的流标志还原器,但请注意,我是在一般解决方案之后,而不是特别还原
std::cout
或o / istream对象还原。实际上,我的类是一种数学对象,它接受自定义类型作为运算符,其中一些需要ostream类似于操纵器的函数,但是通常非常不方便的是要求用户在开始下一次此类使用之前提供一些终结操作数。
我想到的一个想法是,每当在
TSeek
列表中提供args...
时,都返回另一种新的智能类型的临时对象,以便在将最后一个参数转发给它之后,它将自动被销毁,这确实是时候了我想完成我的定稿任务!我应该这样还是...?
最佳答案
嗯...据我所知,流operator<<()
必须恰好接收两个参数。
因此,您无法定义可变参数operator<<()
。
如果您接受通用模板可变参数函数(例如foo()
),那么可以使用C++ 17并不是很难。
要检查TSeek
包中是否存在Args...
类型,您可以将内容写为
constexpr bool withTSeek { (std::is_same<Args, TSeek>{} || ...) };
以下是完整的编译示例
#include <iostream>
#include <utility>
#include <type_traits>
struct TSeek
{ };
std::ostream & operator<< (std::ostream & o, TSeek const &)
{ return o << " [TSeek!] "; }
template <typename ... Args>
std::ostream & foo (std::ostream & o, Args && ... args)
{
constexpr bool withTSeek { (std::is_same<Args, TSeek>{} || ...) };
(o << ... << args);
if ( withTSeek )
o << " --- TSeek detected" << std::endl;
else
o << " --- TSeek NOT detected" << std::endl;
return o;
}
int main ()
{
foo(std::cout, 1, 2, TSeek{}, 5, 7);
foo(std::cout, 11, 13, 17, 19, 23);
}