带有参数的流操纵器如何工作
How do stream manipulators with arguments work?
在Stroustrup C++书中,有一个自定义操纵器接受参数的例子(请参阅随附的代码(。我对结构的创建方式感到困惑。特别是,看起来"smanip"的构造函数有两个int参数,一个用于函数指针"ff",一个用于"ii"。我不明白如何使用以下命令传递 int 参数来创建结构:
cout << setprecision(4) << angle;
此外,调用这些函数的顺序是什么,类型参数 Ch 和 Tr 是如何确定的? 多谢。
// manipulator taking arguments
struct smanip{
iso_base& (*f) (ios_base&, int);
int i;
smanip(ios_base& (*ff)(ios_base&, int), int ii) : f(ff), i(ii){}
};
template<cladd Ch, class Tr>
ostream<Ch, Tr>& operator<<(ostream<Ch, Tr>& os, smanip& m){
return m.f(os, m.i);
}
ios_base& set_precision(ios_base& s, int n){
return s.setprecision(n); // call the member function
}
inline smanip setprecision(int n){
return smanip(set_precision,n);
}
// usage:
cout << setprecision(4) << angle;
setprecision(4)
调用
inline smanip setprecision(int n){
return smanip(set_precision,n);
}
这会创建一个从指向set_precision
函数的指针smanip
,并n
.
struct smanip{
ios_base& (*f) (ios_base&, int);
int i;
smanip(ios_base& (*ff)(ios_base&, int), int ii) : f(ff), i(ii){}
};
smanip
是一个结构,用于保存指向函数的指针和一个整数。 该函数通过引用获取ios_base
和int
,并通过引用返回ios_base
。
此时,该行实际上是这样的:
smanip m(&setprecision, 4);
cout << m << (otherstuff);
与此模板匹配:
template<class Ch, class Tr>
ostream<Ch, Tr>& operator<<(ostream<Ch, Tr>& os, smanip& m){
return m.f(os, m.i);
}
编译器可以从左侧的流中推断出Ch
和Tr
。 在这种情况下,std::cout
. 代码执行m.f(os, m.i)
. 这调用smanip
持有的函数指针,将流和smanip
持有的整数传递给它。
ios_base& set_precision(ios_base& s, int n){
return s.setprecision(n); // call the member function
}
这称为cout.setprecision(n)
.
所以这条线翻译为:
std::cout.setprecision(4) << angle;
操纵器函子将函数指针和 int 作为参数,并在内部存储两者以供以后使用。为了便于阅读,可以在以下两个声明中拆分构造函数的签名:
typedef ios_base& (*f_ptr)(ios_base&,int);
smanip( f_ptr f, int )
也就是说,第一个参数是函数指针,第二个参数是值。
按照示例代码中的执行顺序,首先调用函数setprecision
,该函数将函数指针和值存储在smanip
对象中并返回它。对象被传递给适当的operator<<
,该提取并执行传递参数的当前流上的存储函数指针。
// on the calling end
setprecision(4) // --> construct __s = smanip( set_precision, 4 )
(cout << ) // --> passes __s to `operator<<`
// inside operator<<
return m.f( os, m.i ); // calls: set_precision( os, 4 ) (m.f == &set_precision
// m.i == 4 )
相关文章:
- QSqlquery prepare()和bindvalue()不工作
- 导入库可以跨dll版本工作吗
- 以螺旋方式打印矩阵的程序.(工作不好)
- 对象指针在c++中是如何工作的
- 为什么在Windows上的VS 2019和Clang 9中"size_t"在没有标题的情况下工作
- VSOMEIP-2个设备之间的通信(TCP/UDP)不工作
- 为字符串中每 N 个字符插入空格的函数没有按照我认为的方式工作?
- C++为线程工作动态地分割例程
- 为什么我的 std::ref 无法按预期工作?
- 布尔比较运算符是如何在C++中工作的
- SampleConsensusPrerejective(ext.RANSAC)是如何真正工作的
- 不确定要在我的main中放入什么才能使我的代码正常工作
- 为什么std::condition_variable notify_all的工作速度比notify_one快(对于随机请
- <<操作员在下面的行中工作
- 有人能解释一下为什么下界是这样工作的吗C++的
- ExtractIconEx:可以工作,但偶尔会崩溃
- C++中的memset函数工作不正常
- 当我在第一个循环中使用"auto"时,它工作正常,但是使用"int"它会给出错误,为什么?
- 链表c++插入,所有情况都已检查,但没有任何工作
- 当 int 方法工作正常时,void 方法有何不同,或者为什么我不能调用 void 方法?