我有一些模板函数可以在我的 C++ 项目中将向量聚合成字符串。我需要使用 std::function 将聚合算法从一个函数传递到另一个函数。
template<typename T>
requires (is_convertible_v<T, BYTE> || is_convertible_v<T, CHAR> || is_convertible_v<T, WCHAR> || is_convertible_v<T, LPCSTR> || is_convertible_v<T, LPCWSTR>)
LPCWSTR StringHelper::ImplodeVectorToStringW(vector<T> vectorValues, LPCWSTR lpcwszSeparator)
{
wstring wstrSeparator(lpcwszSeparator);
function<wstring(wstring, T)> fn = [&](wstring total, T current) -> wstring { return total + lpcwszSeparator + ToWString(current); };
wstring wstrResult = Aggregate(vectorValues, wstring(L""), fn);
LPCWSTR lpcwszResult = GetStringBufferW(wstrResult);
return lpcwszResult;
}
template<typename TRet, typename TValue>
basic_string<TRet> Aggregate(vector<TValue> vectorValues, basic_string<TRet> initValue, function<basic_string<TRet>(basic_string<TRet>, TValue)> fnReduce)
{
basic_string<TRet> total = initValue;
for_each(vectorValues.begin(), vectorValues.end(), [&](TValue current) { fnReduce(total, current); });
return total;
}
template<typename T>
requires (is_convertible_v<T, BYTE> || is_convertible_v<T, CHAR> || is_convertible_v<T, WCHAR> || is_convertible_v<T, LPCSTR> || is_convertible_v<T, LPCWSTR>)
wstring StringHelper::ToWString(T Value)
{
wstring wstrResult;
if constexpr(is_convertible_v<T, BYTE>)
{
wstrResult = to_wstring((BYTE)Value);
}
else if constexpr(is_convertible_v<T, CHAR>)
{
wstrResult = AnsiToUnicode(string(1, (CHAR)Value).c_str());
}
else if constexpr(is_convertible_v<T, WCHAR>)
{
wstrResult = wstring(1, (WCHAR)Value);
}
else if constexpr(is_convertible_v<T, LPCSTR>)
{
wstrResult = AnsiToUnicode((LPCSTR)Value);
}
else if constexpr(is_convertible_v<T, LPCWSTR>)
{
wstrResult = (LPCWSTR)Value;
}
return wstrResult;
}
但是当我调试这段代码时,函数 fn 被初始化为以下值:
fn = wstrSeparator = L" ";
不适用于所需的 lambda 表达式。怎么了?
您在函数模板
Aggregate
中所做的事情是调用可调用 vectorValues
的每个元素 fnReduce
,依次复制输入参数 total
和 current
对它们执行某些操作,然后返回您的值丢弃。它相当于NOOP。您到底期望这里发生什么?
学习基本的C++。这不是 Python、Java 或 C#,其中对象默认动态存储。
首先,您进行了大量的字符串复制,这不好,因为您进行了很多不必要的数据复制。
比如说,你可以通过替换来修复它:
function<wstring(wstring&, T const&)> fn = [&](wstring& total, T const& current)
{
total += lpcwszSeparator;
total += ToWString(current);
};
然后,您只需要调整
Aggregate
参数即可使其工作。或者您可以按照@Jarod42的建议进行操作:将 for_each
中的调用替换为 total = fnReduce(total, current);
,速度较慢但更简单。