我有一个使用operator<<<链可以同时向控制台和文件输出内容。我需要在线路断开时冲洗它,这发生在重新定义的endl(替换为\ n)。此代码不起作用并吐出很多错误(没有从T转换为const char *)。有什么问题?
#pragma once
#include <iostream>
#include <fstream>
/*class declaration*/
template <typename T>
inline Logger & Logger::operator<<(const T &a)
{
if (debug::enabled)
{
std::cout << a;
file << a;
if (this->previousLineBroken)
{
std::cout << std::flush;
file << std::flush;
this->previousLineBroken = false;
}
if (std::is_same<T, const char*>::value) {
this->previousLineBroken = (a == debug::endl);
}
return *this;
}
}
从(const T&amp; a)中删除const只会让事情变得更糟,错误更多。
UPD: previousLineBroken是bool,debug :: endl是const char * =“\ n”。
//debug.h
#pragma once
#define logger *logPtr
#include "Classes.h"
#include "logger.h"
namespace debug
{
static const char* endl = "\n";
static const bool enabled = true;
}
using debug::endl;
答案 0 :(得分:4)
您的if
语句不是编译时分支,因此编译器会尝试编译
this->previousLineBroken = (a == debug::endl);
适用于任何T
,即使
std::is_same<T, const char*>::value
是false
。此可能是导致错误的原因。您应该在问题中添加MCVE。
在C ++ 17中,您可以使用if
使if constexpr
成为编译时分支:
if constexpr(std::is_same<T, const char*>::value) {
this->previousLineBroken = (a == debug::endl);
}
在C ++ 11中,您可以使用其他辅助函数和重载:
template <typename T>
void setPreviousLineBroken(std::true_type, T a)
{
this->previousLineBroken = (a == debug::endl);
}
template <typename T>
void setPreviousLineBroken(std::false_type, T) { /* do nothing */ }
您的代码如下所示:
template <typename T>
inline Logger & Logger::operator<<(const T &a)
{
if (debug::enabled)
{
std::cout << a;
file << a;
if (this->previousLineBroken)
{
std::cout << std::flush;
file << std::flush;
this->previousLineBroken = false;
}
setPreviousLineBroken(std::is_same<T, const char*>{});
return *this;
}
}