繁体   English   中英

使用lambda的多图谓词

[英]multimap predicate using lambda

我正在尝试使用多图对一些关系数据进行排序,但是在正确定义谓词时遇到了问题。

  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();
  });

这些类型似乎是正确的,但Visual Studio则相反。

可以使用lambda代替函数指针,但是lambda不是函数指针。 因此,第三个模板参数的类型是错误的。

相反,您可以先定义lambda,然后使用例如decltype来获取lambda类型。 类似于以下代码:

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);

您的比较器模板参数类型为

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

而lambda可以衰减的类型是

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

我建议您也使多图在其比较器参数中也采用引用。

我将介绍一些提到的选项:

选项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);

确实可以编译,但是奇怪的是在Visual Studio错误列表中留下了一个错误(并留下了一个令人讨厌的红色花体):

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 :: function会使(烦人的!)红色花键和错误列表条目消失。 希望这可以帮助!

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM