【发布时间】:2013-01-20 02:10:16
【问题描述】:
我想将操纵器列表传递给函数,如下所示:
void print(const vector<std::smanip>& manips) {
// ...
for (auto m : manips)
cout << m;
// ...
}
理想情况下,它会被这样的代码调用:
some_object.print({std::fixed, std::setprecision(2)}));
g++ 4.7.0 说:
error: ‘std::smanip’ has not been declared
显然,smanip 并没有真正在标准中定义,C++11 编译器不需要为操纵器的类型提供明确的名称。我尝试通过从已知的操纵器中提取来声明类型,如下所示:
typedef decltype(std::fixed) manip;
这打开了许多新的错误消息,包括这个:
error: ‘const _Tp* __gnu_cxx::new_allocator< <template-parameter-1-1>
>::address(__gnu_cxx::new_allocator< <template-parameter-1-1> >::const_reference)
const [with _Tp = std::ios_base&(std::ios_base&); __gnu_cxx::new_allocator<
<template-parameter-1-1> >::const_pointer = std::ios_base& (*)(std::ios_base&);
__gnu_cxx::new_allocator< <template-parameter-1-1> >::const_reference =
std::ios_base& (&)(std::ios_base&)]’ cannot be overloaded
我应该现在就放弃,还是有办法做到这一点?
【问题讨论】:
-
操纵器通常是函数,因此它们没有通用的基类。
-
你可以用一个流操作符定义你自己的包装类,它应用了操纵器和一个通用的基础,并将它用于你的参数?
-
如果你真的想这样做,你可能需要把你的函数写成一个可变参数模板(因为不同的操纵器有不同的类型,其中大部分你不知道)。即使这样,它也不会是微不足道的(例如,您可能还需要使用
std::bind来处理带参数的操纵器)。 -
@JerryCoffin 我相信可变参数函数模板也可以。
-
@Angew:我以为我就是这么说的。反正就是我想说的……
标签: c++ c++11 iostream iomanip