是否有标准化的方法来搜索容器中的值((unordered_)映射的键)?
以此功能为例:
// binding
var binding = new WSHttpBinding();
// using System.ServiceModel
var channelFactory = new ChannelFactory<InfoWcfWS.IInfo>(binding);
// using System.ServiceModel.Description
var endpointClientbehavior = new ClientCredentials();
endpointClientbehavior.ClientCertificate
.SetCertificate(
"This is my TEST Cert",
StoreLocation.LocalMachine,
StoreName.My);
// add the behavior to the endpoint
channelFactory.Endpoint.EndpointBehaviors.Add(endpointClientbehavior);
// done configuring;
channelFactory.Open();
var endpoint = new EndpointAddress(
new Uri(ConfigurationManager.AppSettings["ServiceUrl.Tls12.Info"]));
// create the clientChannel
var client = channelFactory.CreateChannel(endpoint);
client.Open();
// client implements the operations on InfoWcfWS.IInfo
我用:
template <class T, class V> bool find(T const &t, V const &v) {
// For std::vector : return std::find(t.begin(), t.end(), v) != t.end();
// For std::(unordered_)set and (unordered_)map : return t.find(v) != t.end();
return ?
}
但是std有这种东西吗?
答案 0 :(得分:2)
没有什么标准可以帮到你 - 但我们可以轻松地编写这样的解决方案。 “特殊”部分是容器是否具有find()
成员函数。如果是的话,我们应该使用它。如果没有,我们将回归使用std::find()
。无论如何,我们希望将结果与end()
进行比较。
因此,我们为.find()
编写首选重载,为另一个重写 fallback 重载:
template <class C, class V>
auto generic_find_impl(C const& container, V const& value, int /* unused */)
-> decltype(container.find(value))
{
return container.find(value);
}
template <class C, class V>
auto generic_find_impl(C const& container, V const& value, ...)
{
using std::begin;
using std::end;
return std::find(begin(container), end(container), value);
}
template <class C, class V>
bool generic_find(C const& container, V const& value) {
using std::end;
return generic_find_impl(container, value, 0) != end(container);
}
如果container.find(value)
是有效表达式,则由于最后一个参数(int
与0
的匹配比...
更好),首选重载将是首选。如果它不是一个有效的表达式,那么第一个重载是不可行的,我们只得到第二个重载。
答案 1 :(得分:-1)
所以你基本上问的是有没有能为你调用t.find
的功能?不。库基础知识TS v2提出了一系列非成员erase
和erase_if
重载,这些重载是这样实现的:
template<typename _Key, typename _Compare, typename _Alloc,
typename _Predicate>
inline void
erase_if(set<_Key, _Compare, _Alloc>& __cont, _Predicate __pred)
{ __detail::__erase_nodes_if(__cont, __pred); }
template<typename _Key, typename _Compare, typename _Alloc,
typename _Predicate>
inline void
erase_if(multiset<_Key, _Compare, _Alloc>& __cont, _Predicate __pred)
{ __detail::__erase_nodes_if(__cont, __pred); }
另一方面,以下是list
:
template<typename _Tp, typename _Alloc, typename _Predicate>
inline void
erase_if(list<_Tp, _Alloc>& __cont, _Predicate __pred)
{ __cont.remove_if(__pred); }
template<typename _Tp, typename _Alloc, typename _Up>
inline void
erase(list<_Tp, _Alloc>& __cont, const _Up& __value)
{
using __elem_type = typename list<_Tp, _Alloc>::value_type;
erase_if(__cont, [&](__elem_type& __elem) { return __elem == __value; });
}
正如您所看到的,无法进行均匀擦除。逻辑同样延伸到find
。你的方法很好,但我会遵循标准的风格,并为比较器,分配器等添加模板参数,以便健壮。
答案 2 :(得分:-1)
您可以为find_if函数提供一元谓词
template <class K, class V> bool find(std::unordered_map<K, V> const &t, K const &v) {
return std::find_if(t.begin(), t.end(), [v](const std::pair<K, V>& x) {return x.first == v; }) != t.end();
}
int main()
{
std::unordered_map<int,char> example = {{1,'a'},{2,'b'}};
std::cout << find(example, 2); // true
std::cout << find(example, 3); // false
}