gpt4 book ai didi

c++ - 为什么 `<< std::endl` 不调用我希望它调用的运算符(operator)?

转载 作者:IT老高 更新时间:2023-10-28 12:47:56 27 4
gpt4 key购买 nike

我正在寻找一种同时写入文件和控制台的解决方案。我找到了一个不错的解决方案 here .

由于我在 C++11 之前工作,因此我不得不对 Lightness Races in Orbit 中的代码进行一些小改动:

#include <iostream>
#include <fstream>
#include <string>

struct OutputAndConsole : std::ofstream
{
OutputAndConsole(const std::string& fileName)
: std::ofstream(fileName.c_str()) // constructor taking a string is C++11
, fileName(fileName)
{};

const std::string fileName;
};

template <typename T>
OutputAndConsole& operator<<(OutputAndConsole& strm, const T& var)
{
std::cout << var;
static_cast<std::ofstream&>(strm) << var;
return strm;
};

除了一件小事让我困惑之外,它工作得很好。如果我这样使用它:

int main(){
OutputAndConsole oac("testLog.dat");
double x = 5.0;
oac << std::endl;
static_cast<OutputAndConsole&>(oac << "foo \n" << x << "foo").operator<<(std::endl);
oac << "foo" << std::endl;
}

然后所有 std::endl当它们在文件中正确显示时,控制台上的输出将被忽略。我的猜测是,当我使用 std::endl ostream::operator<<被调用,它将打印到文件而不是控制台。带有 static_cast<OutputAndConsole&> 的行是我尝试调用正确运算符的业余尝试,但仍然只是 \n 中的换行符出现在控制台上。

为什么选择 std::endl调用了错误的运算符?

我怎样才能调用正确的?

PS:我知道我可以用\n没有问题,但我仍然想知道这里发生了什么以及如何解决它。

最佳答案

struct OutputAndConsole : std::ofstream
{
// ...
};

template <typename T>
OutputAndConsole& operator<<(OutputAndConsole& strm, const T& var);

正如其他人提到的,std::endl是一个模板函数。模板函数不是一个值,它只是一个名称。

如果您尝试将模板函数传递给期望具有兼容签名的函数的函数,则可以将其转换为值。如果传递给采用 T 的模板函数,它转换为值或 const T& ,因为模板函数的名称代表了可能值的整个宿主

因为std::endl不是您自定义编写的有效参数 operator<< ,它看起来在别处。它找到 std::ofstreamoperator<<通过显式函数指针获取 io 操纵器函数。

那个有效,它可以转换endl到那个函数指针类型!所以,它兴高采烈地叫它。

要解决此问题,请添加 operator<<重载到 OutputAndConsole这需要 io 操纵器函数指针。

最简单的方法是编写一个辅助函数:

template <class T>
void output_to(OutputAndConsole& strm, const T& var)
{
std::cout << var;
static_cast<std::ofstream&>(strm) << var;
};

然后是两个 <<重载:

template<class T>
OutputAndConsole& operator<<(OutputAndConsole& strm, const T& var) {
output_to(strm, var);
return strm;
}
OutputAndConsole& operator<<(OutputAndConsole& strm, std::ostream& (*var)(std::ostream&)) {
output_to(strm, var);
return strm;
}

导致 std::endl模板查找匹配 << .

关于c++ - 为什么 `<< std::endl` 不调用我希望它调用的运算符(operator)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38074998/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com