ubb*_*bdd 8 c++ stream manipulators
在Stroustrup的C++书中,有一个自定义操纵器采用参数的例子(请参阅附带的代码).我对如何创建结构感到困惑.特别是,看起来"smanip"的构造函数有两个int参数,一个用于函数指针"ff",一个用于"ii".我不明白如何通过使用传递int参数来创建结构:
cout << setprecision(4) << angle;
Run Code Online (Sandbox Code Playgroud)
另外,调用这些函数的顺序是什么,以及如何确定类型参数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;
Run Code Online (Sandbox Code Playgroud)
setprecision(4)
Run Code Online (Sandbox Code Playgroud)
电话
inline smanip setprecision(int n){
return smanip(set_precision,n);
}
Run Code Online (Sandbox Code Playgroud)
这会smanip从指向set_precision函数的指针创建一个n.
struct smanip{
ios_base& (*f) (ios_base&, int);
int i;
smanip(ios_base& (*ff)(ios_base&, int), int ii) : f(ff), i(ii){}
};
Run Code Online (Sandbox Code Playgroud)
smanip是一个结构,它包含一个指向函数的指针和一个整数.该函数采用ios_base引用和a int,并返回ios_base引用.
在这一点上,这条线实际上是这样的:
smanip m(&setprecision, 4);
cout << m << (otherstuff);
Run Code Online (Sandbox Code Playgroud)
与此模板匹配:
template<class Ch, class Tr>
ostream<Ch, Tr>& operator<<(ostream<Ch, Tr>& os, smanip& m){
return m.f(os, m.i);
}
Run Code Online (Sandbox Code Playgroud)
而编译器可以推断出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
}
Run Code Online (Sandbox Code Playgroud)
这叫cout.setprecision(n).
所以该行转换为:
std::cout.setprecision(4) << angle;
Run Code Online (Sandbox Code Playgroud)
操纵器仿函数接受一个函数指针和一个 int 作为参数,并将两者存储在内部以供以后使用。为了便于阅读,构造函数的签名可以分为这两个声明:
typedef ios_base& (*f_ptr)(ios_base&,int);
smanip( f_ptr f, int )
Run Code Online (Sandbox Code Playgroud)
也就是说,第一个参数是函数指针,第二个参数是值。
按照示例代码中的执行顺序,首先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 )
Run Code Online (Sandbox Code Playgroud)