如何将模板参数传递给std::function?

问题描述 投票:0回答:1

我有一些模板函数可以在我的 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 表达式。怎么了?

c++ templates std
1个回答
0
投票

您在函数模板

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);
,速度较慢但更简单。

© www.soinside.com 2019 - 2024. All rights reserved.