简单的I / O操纵器无法按预期工作

时间:2013-12-26 14:57:47

标签: c++ io

以下代码:

#include <iostream>

std::ios_base &my_manip (std::basic_ios<char> &os) {
    os.unsetf(std::ios_base::basefield);
    os.setf(std::ios_base::scientific);
    return os;
}

int main (int argc, char **argv) {
    std::cout << 8.8888888 << std::endl;
    std::cout << my_manip << 8.8888888 << std::endl;
    return 0;
}

打印:

8.88889

18.88889

以下代码:

#include <iostream>

std::ios_base &my_manip (std::basic_ios<char> &os) {
    os.unsetf(std::ios_base::basefield);
    os.setf(std::ios_base::scientific);
    return os;
}

int main (int argc, char **argv) {
    std::cout << 8.8888888 << std::endl;
    my_manip(std::cout);
    std::cout << 8.8888888 << std::endl;
    return 0;
}

打印预期结果:

8.88889

8.888889e+00

有人可以告诉我第一个版本有什么问题吗?

3 个答案:

答案 0 :(得分:5)

自定义操纵器签名不匹配,

你应该这样做:

std::ostream& my_manip (std::ostream &os) {
    os.unsetf(std::ios_base::basefield);
    os.setf(std::ios_base::scientific);
    return os;
}

std::cout << my_manip << 8.8888888 << std::endl;

答案 1 :(得分:2)

有三个重载采用了一个可用于操纵器的函数指针。这三个签名是

std::ios_base&                  (*)(std::ios_base&)
std::basic_ios<cT, Traits>&     (*)(std::basic_ios<cT, Traits>&);
std::basic_ostream<cT, Traits>& (*)(std::basic_ostream<cT, Traits>&);

您使用的签名(std::ios_base&(*)(std::basic_ios<cT, Traits>&))不是这些。

我假设您使用实际设置作为示例,因为std::scientific操纵器已经实现了示例代码尝试实现的逻辑。

答案 2 :(得分:1)

问题似乎是你操纵者的签名。如果将其更改为

std::basic_ostream<char> &my_manip (std::basic_ostream<char> &os)

然后它按预期工作。