代码之家  ›  专栏  ›  技术社区  ›  Gubatron

定义STD::基于模板的键类型的映射,该函数基于作为参数接收的函数

  •  0
  • Gubatron  · 技术社区  · 6 年前

    我的目标是让一个函数返回一个映射,该映射的键类型可以根据作为参数传递给我的函数的函数而改变。

    我有以下模板功能(C++ 11)作为迄今为止唯一可编译的解决方案:

        template <typename Container, typename Function, typename KeyType>
        std::map< KeyType, std::vector<typename Container::value_type> > 
        group_by(Container &container, Function function, KeyType keyHint) { ...
    

    现在我可以这样使用函数:

    // the last parameter is just a type hint for the compiler
    std::map<int, std::vector<int>> m = group_by(vec, func_that_returns_an_int, 1337);
    ...
    std::map<int, std::vector<int>> m = group_by(vec, func_that_returns_an_int, -1);
    
    // if we pass a function that returns bool, the map's key will be boolean
    // the last parameter passed is just a hint for the compiler
    std::map<bool, std::vector<int>> m = group_by(vec, is_even, true);
    ...
    std::map<bool, std::vector<int>> m = group_by(vec, is_even, false);
    

    我的目标是不必传递随机值来提示编译器映射的键类型应该是什么,我希望我可以这样做:

    std::map<int, std::vector<int>> m = group_by<int>(vec, func_that_returns_an_int);
    ...
    std::map<bool, std::vector<int>> m = group_by<bool>(vec, is_even);
    

    或者这也是可能的?

    std::map<bool, std::vector<int>> m = group_by(vec, is_even);
    

    我在玩auto和decltype,看看编译器是否能被操作的左侧所暗示,而不是运气好。

    auto group_by(Container &container, Function function) -> std::map< decltype(function(Container::value_type)), >
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   Jarod42    6 年前

    更改订单或模板参数将允许您调用它

    group_by<int>(vec, func_that_returns_an_int);
    

    所以改变

    template <typename Container, typename Function, typename KeyType>
    std::map< KeyType, std::vector<typename Container::value_type> > 
    group_by(Container &container, Function function, KeyType keyHint)
    

    template <typename KeyType, typename Container, typename Function>
    std::map< KeyType, std::vector<typename Container::value_type> > 
    group_by(Container &container, Function function)
    

    完全移除 KeyType ,您必须从其他参数推断:

    template <typename Container, typename Function>
    auto group_by(Container &container, Function function)
    -> std::map<decltype(function(*container.begin())),
                std::vector<typename Container::value_type> > 
    
        2
  •  1
  •   Swordfish    6 年前

    你可以用 std::result_of<> :

    #include <map>
    #include <vector>
    #include <type_traits>
    
    template <typename Container, typename Function, typename KeyType = std::result_of_t<Function()>>
    auto group_by(Container c, Function f) -> std::map< KeyType, std::vector<typename Container::value_type>>
    {
        return // ...
    }
    
    int bar() { return 42; }
    
    int main()
    {
        auto v = group_by(std::vector<double>{}, bar);
    }