C ++ determines if container :: find () has

I have a functor that works on a container of type U elements of type T , for example,

 template<typename T, template<typename...> class U> class asserter { public: asserter(U<T> &c) : container(c) { }; void operator()(T lhs) { CU_ASSERT(container.find(lhs) != container.end()); }; private: U<T> &container; }; 

which i could use as

 std::set<std::string> a, c; ... asserter<std::string, std::set> ass(c); for_each(a.begin(), a.end(), ass); 

We are currently ignoring std::includes() .

This works fine if the U::find() parameter is specified in the container. If this is not the case, I would like to return to std::find() . On the other hand, I would prefer to use U::find() over std::find() , if available.

In C ++ 11 (or 17, if necessary) can I determine if U::find() (possibly limited to STL) for U, and if it uses it, otherwise use std::find() ?

+7
c ++ c ++ 11 stl traits sfinae
source share
1 answer

SFINAE on the correct formation of the expression c.find(value) . Trailing return type is C ++ 11, and in any case it is not so important; it just simplifies writing the return type - decltype(c.find(value)) instead of decltype(std::declval<Container&>().find(std::declval<const T&>())) .

If the expression is poorly formed, the first find_impl overload will be removed from the overload set, leaving the second overload as the only viable one. The usual int/long/0 trick for the third parameter makes the first overload preferable when both are viable.

 template<class Container, class T> auto find_impl(Container& c, const T& value, int) -> decltype(c.find(value)){ return c.find(value); } template<class Container, class T> auto find_impl(Container& c, const T& value, long) -> decltype(std::begin(c)){ return std::find(std::begin(c), std::end(c), value); } template<class Container, class T> auto find(Container& c, const T& value) -> decltype(find_impl(c, value, 0)) { return find_impl(c, value, 0); } 

The usual denial expression applies: it depends on the SFINAE expression, which is not currently supported by MSVC; Microsoft plans to add support for the upgrade to MSVC 2015.

+7
source share

All Articles