gpt4 book ai didi

c++ - 如何检查模板中发送的参数类型?

转载 作者:行者123 更新时间:2023-12-03 06:58:54 24 4
gpt4 key购买 nike

我正在尝试创建一个简单的记录器,将不同的消息记录到磁盘。记录器是一个简单的类,我重写了<<运算符,并且为了保存消息,我发送了一个枚举值信号来保存到目前为止的内容。基本上将所有内容刷新到磁盘。
这就是我打算使用此记录器的方式:

Logging::Logger << "First " << 255 << "Second" << exc.what() << Logging::Save;
如您所见,由于我需要一种区分诸如 Logging::Save之类的控制参数和其他普通参数的方法,因此我需要知道我要处理的内容。
为了获得发送的参数类型,我使用了 std::is_same。但是,由于某些原因,该检查不起作用,并且出现以下错误:
 In instantiation of 'Logging::Log& Logging::Log::operator<<(const T&) [with T = char [19]]':
104:35: required from here
47:31: error: no match for 'operator==' (operand types are 'const char [19]' and 'Logging::Mode')
In instantiation of 'Logging::Log& Logging::Log::operator<<(const T&) [with T = Logging::Mode]':
104:67: required from here
57:28: error: cannot bind 'std::basic_ostream<char>' lvalue to 'std::basic_ostream<char>&&'
In file included from /usr/include/c++/4.9/iostream:39:0,
from 10:
/usr/include/c++/4.9/ostream:602:5: note: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char; _Traits = std::char_traits<char>; _Tp = Logging::Mode]'
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^

到目前为止,这是我提出的:
#include <iostream>
#include <fstream>
#include <sstream>
#include <typeinfo>
#include <type_traits>

namespace Logging
{
enum class Mode
{
Save = 0,
Load = 1
};
static constexpr Mode Save = Mode::Save;

class Log
{
private:
std::stringstream stream;
bool isNew = true;
bool displayResults = false;

public:

template <typename T>
Log& operator<<(const T& value)
{
if (isNew)
{
stream << "start : ";
isNew = false;
}

if (std::is_same<T, Logging::Mode>::value)
{
if (value == Mode::Save)
Save();

if (displayResults)
std::cout << std::endl;

isNew = true;
}
else
{
stream << value;
}

if (displayResults)
std::cout << stream.str();

return *this;
}

void Save(std::string logFilename= "Log.txt")
{
isNew = true;

std::ofstream logFile;
logFilename = (logFilename == "") ? "Log.txt" : logFilename;
logFile.open(logFilename, std::ios::out | std::ios::app);

logFile << this->Get();

this->stream.clear();
this->stream.str("");
}

Log& Display(bool status)
{
displayResults = status;
return *this;
}
std::string Get() const
{
return this->stream.str();
}

friend std::ostream& operator<<(std::ostream& os, const Log& log);
};

std::ostream& operator<<(std::ostream& os, const Log& log)
{
os << log.Get();
return os;
}

Log Logger;
}

int main()
{
Logging::Logger.Display(true)<< "What is your name?" <<Logging::Save;
}

我在这里想念什么?

最佳答案

您几乎完全正确,if constexpr(std::is_same<T, Logging::Mode>::value)是C++ 17中想要的。
没有constexpr,无论条件如何,都会编译if语句的主体,即使在这种情况下从不采用分支,这的确会产生关于将数组与枚举进行比较的错误。'operator==' (operand types are 'const char [19]' and 'Logging::Mode')
考虑使用通用引用template<typename T> T&&和完美的转发来传递value。这是一个好习惯。
在您的情况下,一个简单的重载辅助方法也可以工作:

template <typename T>
Log& operator<<(T&& value)
{
if (isNew)
{
stream << "start : ";
isNew = false;
}

helper(std::forward<T>(value));

if (displayResults)
std::cout << stream.str();

return *this;
}
template<typename T>
void helper(T&& value){
stream << std::forward<T>(value);
}
// Perfect forwarding requires that the enum is taken by value,
// otherwise the template is a better match in some cases.
// - Or you would have to write both const& and && versions.
void helper(Logging::Mode value){
if (value == Mode::Save)
Save();

if (displayResults)
std::cout << std::endl;

isNew = true;
}

关于c++ - 如何检查模板中发送的参数类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64116744/

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