完美转发参数包:转换参数而不扩展?
perfect foward a parameter pack: convert args without expansion?
在单元测试中,我试图实现更实用的代码并简化 class 函数调用,例如:
std::wstring widestr = std::wstring(o.Descr.begin(), o.Descr.end()); //o.Descr is string
wchar_t message[100];
swprintf(message, 100, L"size: %d", size);
Logger::WriteMessage(message);
进入:
Logger::WriteMessage(Message(L"string: %d", widestr.c_str()));
使用:
template<typename... T>
wchar_t* Message(T &&... args)
{
wchar_t message[100];
swprintf(message, 100, forward<T>(args)...);
return message;
}
但输出不同:
而不是
1。我首先做的是正确的事吗?我想念什么?
2。理想情况下,我想写类似 (c#):
的东西
$"size:{size}".ToLogMessage();
我想我不能用 c++{11,14,17}。你确认吗?
Logger::WriteMessage
是 Microsoft.VisualStudio.TestTools.CppUnitTestFramework 的一部分,我无法更改它。
主要问题是你没有展开包:
template <typename... T>
wchar_t* Message(T &&... args)
{
wchar_t message[100];
swprintf(message, 100, forward<T>(args)...);
return message;
}
但是,您还 return 悬挂指针,这是个大问题。
最终,如果 Logger::WriteMessage
必须 接受一个指针,您将不得不在实用程序中包含所有三行代码。也许像:
template <typename... T>
void WriteLogMessage(T &&... args)
{
wchar_t message[100];
swprintf(message, 100, forward<T>(args)...);
Logger::WriteMessage(message);
}
然后只是:
WriteLogMessage(L"size: %d", size));
现在我要请你考虑一下 Logger::WriteMessage
是否应该首先自己做这一切。
一旦你开始了,你可以考虑从 swprintf
切换到更像 C++ 的东西,这样你就不需要依赖一些任意的最大缓冲区大小。但是,使用 stringstreams 和字符串并不是世界上最有效的事情,因此您还可以考虑执行 swprintf
两次:一次使用 nullptr
输出只是为了获得结果字符串的大小,然后再次实际将其放入大小正确的 wchar_t
数组中……
……不幸的是,这只有 snprintf
才有可能;对于宽字符串,您必须反复尝试使用越来越大的缓冲区,直到 return 值表明您提供的缓冲区终于足够大。呃.
在单元测试中,我试图实现更实用的代码并简化 class 函数调用,例如:
std::wstring widestr = std::wstring(o.Descr.begin(), o.Descr.end()); //o.Descr is string
wchar_t message[100];
swprintf(message, 100, L"size: %d", size);
Logger::WriteMessage(message);
进入:
Logger::WriteMessage(Message(L"string: %d", widestr.c_str()));
使用:
template<typename... T>
wchar_t* Message(T &&... args)
{
wchar_t message[100];
swprintf(message, 100, forward<T>(args)...);
return message;
}
但输出不同:
而不是
1。我首先做的是正确的事吗?我想念什么?
2。理想情况下,我想写类似 (c#):
的东西$"size:{size}".ToLogMessage();
我想我不能用 c++{11,14,17}。你确认吗?
Logger::WriteMessage
是 Microsoft.VisualStudio.TestTools.CppUnitTestFramework 的一部分,我无法更改它。
主要问题是你没有展开包:
template <typename... T>
wchar_t* Message(T &&... args)
{
wchar_t message[100];
swprintf(message, 100, forward<T>(args)...);
return message;
}
但是,您还 return 悬挂指针,这是个大问题。
最终,如果 Logger::WriteMessage
必须 接受一个指针,您将不得不在实用程序中包含所有三行代码。也许像:
template <typename... T>
void WriteLogMessage(T &&... args)
{
wchar_t message[100];
swprintf(message, 100, forward<T>(args)...);
Logger::WriteMessage(message);
}
然后只是:
WriteLogMessage(L"size: %d", size));
现在我要请你考虑一下 Logger::WriteMessage
是否应该首先自己做这一切。
一旦你开始了,你可以考虑从 swprintf
切换到更像 C++ 的东西,这样你就不需要依赖一些任意的最大缓冲区大小。但是,使用 stringstreams 和字符串并不是世界上最有效的事情,因此您还可以考虑执行 swprintf
两次:一次使用 nullptr
输出只是为了获得结果字符串的大小,然后再次实际将其放入大小正确的 wchar_t
数组中……
……不幸的是,这只有 snprintf
才有可能;对于宽字符串,您必须反复尝试使用越来越大的缓冲区,直到 return 值表明您提供的缓冲区终于足够大。呃.