使用lambda多重映射谓词(multimap predicate using lambda)

2019-10-20 09:10发布

我试图使用多重映射关系的一些数据进行排序,但我有得到正确定义谓词的问题。

  std::multimap<
      std::vector<Message>, std::string,
      bool (*)(const std::vector<Message>, const std::vector<Message>)>
  sortmap([&](const std::vector<Message> &lhs,
              const std::vector<Message> &rhs) {
    return lhs.size() < rhs.size();
  });

该类型似乎是正确的,但视觉工作室否则说。

Answer 1:

你比较模板参数类型

bool (*)(const std::vector<Message>, const std::vector<Message>)

而类型拉姆达可以衰减到是

bool (*)(const std::vector<Message>&, const std::vector<Message>&)

我建议你multimap中采取了比较参数引用过。



Answer 2:

一个lambda来代替一个函数指针的使用,但拉姆达不是一个函数指针。 因此,第三个模板参数的类型是错误的。

相反,你可以先定义拉姆达,并使用如decltype获得λ类型。 类似下面的代码:

auto comparator = [](const std::vector<Message>& lhs,
                     const std::vector<Message>& rhs) {
    return lhs.size() < rhs.size();
};

std::multimap<std::vector<Message>, std::string, decltype(comparator)> sortmap(comparator);


Answer 3:

我会去通过一些提到的选项:

选项1 @Joachim Pilborg

  auto comparator = [](const std::vector<Message>& lhs,
    const std::vector<Message>& rhs) {
    return lhs.size() < rhs.size();
  };

  std::multimap<std::vector<Message>, std::string, decltype(comparator)> sortmap(comparator);

  Message msg;
  std::vector<Message> messages;
  messages.push_back(msg);

  std::string str;
  auto test = std::make_pair(messages, str);

  sortmap.emplace(test);

结果是

1>c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtree(1007): error C3497: you cannot construct an instance of a lambda
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtree(1006) : while compiling class template member function 'main::<lambda_2efe1f793bd1dfe8b84381ab9a3a87dc> std::_Tree_comp<false,_Traits>::_Getcomp(void) const'
1>          with
1>          [
1>              _Traits=std::_Tmap_traits<std::vector<Message,std::allocator<Message>>,std::string,main::<lambda_2efe1f793bd1dfe8b84381ab9a3a87dc>,std::allocator<std::pair<const std::vector<Message,std::allocator<Message>>,std::string>>,true>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtree(1789) : see reference to function template instantiation 'main::<lambda_2efe1f793bd1dfe8b84381ab9a3a87dc> std::_Tree_comp<false,_Traits>::_Getcomp(void) const' being compiled
1>          with
1>          [
1>              _Traits=std::_Tmap_traits<std::vector<Message,std::allocator<Message>>,std::string,main::<lambda_2efe1f793bd1dfe8b84381ab9a3a87dc>,std::allocator<std::pair<const std::vector<Message,std::allocator<Message>>,std::string>>,true>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\xtree(1024) : see reference to class template instantiation 'std::_Tree_comp<false,_Traits>' being compiled
1>          with
1>          [
1>              _Traits=std::_Tmap_traits<std::vector<Message,std::allocator<Message>>,std::string,main::<lambda_2efe1f793bd1dfe8b84381ab9a3a87dc>,std::allocator<std::pair<const std::vector<Message,std::allocator<Message>>,std::string>>,true>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 12.0\vc\include\map(275) : see reference to class template instantiation 'std::_Tree<std::_Tmap_traits<_Kty,_Ty,_Pr,_Alloc,true>>' being compiled
1>          with
1>          [
1>              _Kty=std::vector<Message,std::allocator<Message>>
1>  ,            _Ty=std::string
1>  ,            _Pr=main::<lambda_2efe1f793bd1dfe8b84381ab9a3a87dc>
1>  ,            _Alloc=std::allocator<std::pair<const std::vector<Message,std::allocator<Message>>,std::string>>
1>          ]
1>          c:\users\c\documents\visual studio 2013\projects\project1\project1\source.cpp(15) : see reference to class template instantiation 'std::multimap<std::vector<Message,std::allocator<_Ty>>,std::string,main::<lambda_2efe1f793bd1dfe8b84381ab9a3a87dc>,std::allocator<std::pair<const _Kty,std::basic_string<char,std::char_traits<char>,std::allocator<char>>>>>' being compiled
1>          with
1>          [
1>              _Ty=Message
1>  ,            _Kty=std::vector<Message,std::allocator<Message>>
1>          ]

选项2个 @PlasmaHH

  std::multimap<
      std::vector<Message>, std::string,
      bool (*)(const std::vector<Message> &, const std::vector<Message> &)>
  sortmap([&](const std::vector<Message> &lhs,
              const std::vector<Message> &rhs) {
    return lhs.size() < rhs.size();
  });
  Message msg;
  std::vector<Message> messages;
  messages.push_back(msg);

  std::string str;
  auto test = std::make_pair(messages, str);

  sortmap.emplace(test);

这是否编译,但奇怪的是叶视觉工作室错误列表错误(并留下一个恼人的红色波浪线):

1   IntelliSense: no instance of constructor "std::multimap<_Kty, _Ty, _Pr, _Alloc>::multimap [with _Kty=std::vector<Message, std::allocator<Message>>, _Ty=std::string, _Pr=bool (*)(const std::vector<Message, std::allocator<Message>> &, const std::vector<Message, std::allocator<Message>> &), _Alloc=std::allocator<std::pair<const std::vector<Message, std::allocator<Message>>, std::string>>]" matches the argument list
        argument types are: (lambda []bool (const std::vector<Message, std::allocator<Message>> &lhs, const std::vector<Message, std::allocator<Message>> &rhs)->bool)  c:\Users\c\Documents\Visual Studio 2013\Projects\Project1\Project1\Source.cpp   12

}

我不是与解决

  auto comparator = [](const std::vector<Message> &lhs,
    const std::vector<Message> &rhs) {
    return lhs.size() < rhs.size();
  };
  std::multimap<std::vector<Message>, std::string,
    std::function<bool(const std::vector<Message> &,
    const std::vector<Message> &) >>
    sortmap(comparator);
  Message msg;
  std::vector<Message> messages;
  messages.push_back(msg);

  std::string str;
  auto test = std::make_pair(messages, str);

  sortmap.emplace(test);

选项1好像不工作:

https://connect.microsoft.com/VisualStudio/feedback/details/727957/vc11-beta-compiler-fails-to-compile-lambda-key-comparer-for-maps-and-sets

明确定义类型的作品,并使用std ::函数出于某种原因使(烦人!)红色波浪线和错误列表条目消失。 希望这可以帮助!



文章来源: multimap predicate using lambda