简体   繁体   English

模板函数对值进行分组的更优雅方式?

[英]A more elegant way for a template function grouping values?

The following code groups values for any container with a generic grouping lambda:以下代码使用通用分组 lambda 对任何容器的值进行分组:

template<class Iterator, class GroupingFunc,
         class T = remove_reference_t<decltype(*declval<Iterator>())>,
         class GroupingType = decltype(declval<GroupingFunc>()(declval<T&>()))>
auto groupValues(Iterator begin, Iterator end, GroupingFunc groupingFunc) {
    map<GroupingType, list<T>> groups;
    for_each(begin, end,
        [&groups, groupingFunc](const auto& val){
            groups[groupingFunc(val)].push_back(val);
    } );
    return groups;
}

With the following usage:有以下用法:

int main() {
    list<string> strs = {"hello", "world", "Hello", "World"};
    auto groupOfStrings =
        groupValues(strs.begin(), strs.end(), 
            [](auto& val) {
                return (char)toupper(val.at(0));
        });
    print(groupOfStrings); // assume a print method

    list<int> numbers = {1, 5, 10, 24, 13};
    auto groupOfNumbers =
        groupValues(numbers.begin(), numbers.end(), 
            [](int val) {
                int decile = int(val / 10) * 10;
                return to_string(decile) + '-' + to_string(decile + 9);
        });
    print(groupOfNumbers); // assume a print method
}

I am a bit reluctant regarding the (over?)-use of declval and decltype in groupValues function.对于groupValues函数中declvaldecltype的(过度?)使用,我有点不情愿。

Do you see a better way for writing it?你看到更好的写作方式了吗?

(Question is mainly for better style and clarity unless of course you see any other issue). (问题主要是为了更好的风格和清晰度,当然除非您看到任何其他问题)。


Code: http://coliru.stacked-crooked.com/a/f65d4939b402a750代码: http : //coliru.stacked-crooked.com/a/f65d4939b402a750

I would probably move the last two template parameters inside the function, and use std::result_of to give a slightly more tidy function:我可能会在函数内移动最后两个模板参数,并使用 std::result_of 来提供稍微更整洁的函数:

template <typename T>
using deref_iter_t = std::remove_reference_t<decltype(*std::declval<T>())>;

template<class Iterator, class GroupingFunc>
auto groupValues(Iterator begin, Iterator end, GroupingFunc groupingFunc) {
    using T = deref_iter_t<Iterator>;
    using GroupingType = std::result_of_t<GroupingFunc(T&)>;
    std::map<GroupingType, std::list<T>> groups;
    std::for_each(begin, end, [&groups, groupingFunc](const auto& val){
        groups[groupingFunc(val)].push_back(val);
    });
    return groups;
}

live demo现场演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 一种更优雅的编写重复代码(模板)的方式? - A more elegant way of writing repetitive code (template)? 使C ++成员函数根据模板参数更改不同成员变量的更简洁方法? - More elegant way to make a C++ member function change different member variables based on template parameter? 使用模板调度模板化 function 的优雅方式 - Elegant way to use template to dispatch templated function 一种将派生类型传递给基本成员模板函数的优雅方法? - An elegant way to pass derived type to base member template function? 重载模板类的更优雅的解决方案 - More elegant solution on overloaded template classes C ++更优雅的方式在多维数组中设置默认值 - C++ More Elegant Way to set Default Values in multi-dimensional array 具有函数参数的C ++函数更加优雅 - C++ function with function parameter more elegant 返回列表索引的更优雅的方法 - More elegant way to return index of a list 有没有一种更优雅的方式在构造函数中声明默认变量? - is there a more elegant way of declaring default variables in a constructor? 优雅的方法,以避免不依赖于模板类型的多个模板实例化的函数 - Elegant way to avoid multiple template instantiatons of function that doesn't depend on templated type
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM