8

在 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;
4

2 回答 2

9
setprecision(4)

来电

inline smanip setprecision(int n){
    return smanip(set_precision,n);
}

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

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;
于 2011-10-28T21:55:05.210 回答
0

manipulator functor 接受一个函数指针和一个 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 )
于 2011-10-28T21:54:04.477 回答