如何在变量函数参数列表中检测给定类型的参数的可用性,并在处理完所有参数后采取行动

How to detect availability of a parameter of given type in variadic funtion arguments list and act after all parameters have been processed

本文关键字:参数 处理 可用性 列表 函数 检测 类型 变量      更新时间:2023-10-16

对于我的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的类似操纵器的函数,但要求用户在开始下一次使用之前提供一些最终操作数通常非常不方便。

我想到的一个想法是,每当args...列表中提供TSeek时,都会返回一个新智能类型的不同类型的临时对象,这样,在最后一个参数转发给它之后,它就会自动被销毁,这真的是我想要完成最终任务的时候了!

我应该这样做还是。。。?

嗯。。。据我所知,流operator<<()必须接收恰好两个参数。

所以你不能定义一个可变的operator<<()

如果你接受一个通用的模板变量函数,例如foo(),如果你能使用C++17,那就不难了。

要检查Args...包中是否存在类型TSeek,可以将其写为

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);
}