I'm annoyed that STL containers don't have a, well, contains()
method returning true
if the container contains an element, false
otherwise. So, I sat down and wrote this:
template <typename C, typename E>
inline bool contains(const C& container, const E& element) {
return container.find(element) != container.end();
}
which works well enough for sets and maps, but not for vectors. Or lists. How should I proceed? Should I write an additional
template <typename T>
inline bool contains(const vector<T>& container, const T& element) {
std::find(vector.begin(), vector.end(), item) != vector.end()
}
and more specific code for other containers? Should I instead settle on the sub-optimal use of iterators to check element-by-element? I would really much rather not do that... perhaps I'm not noticing some relevant STL functionality?
A style is a set of formatting attributes that define the appearance of an element in the document. For example, a character style will contain font or font face attributes, while a paragraph style will contain paragraph alignment and line spacing attributes.
The style attribute specifies an inline style for an element. The style attribute will override any style set globally, e.g. styles specified in the <style> tag or in an external style sheet. The style attribute can be used on any HTML element (it will validate on any HTML element.
There are three ways you can use to implement CSS into your HTML: internal, external, and inline styles.
The <style> tag in HTML helps us to modify our text, viewed in the page. This modification includes changing font size, font family, font color etc. Not only the texts but also we can change the style of a body ar part of a page.
I think one reason is for the absence of a std::contains
returning a bool
is that it is too easy for novice programmers to fall into the trap
if (std::contains(my_container, some_element)) {
auto it = std::find(begin(my_container), end(my_container), some_element);
// process *it
}
and now you are doing twice the work you need.
It is simply idiomatic to write
auto it = std::find(begin(my_container), end(my_container), some_element);
if (it != end(my_container)) {
// process *it
}
If you insist on having a contains
function, you could aim for the best of both worlds by returning a std::pair<bool, iterator>
or a std::optional<iterator>
(coming in a library fundamentals Technical Specification, or already present in Boost) that you can query like this:
if (opt = std::contains(my_container, some_element)) {
// process *opt
}
If you intend to use this function only on STL containers, and if you further have no need to process the iterator returned by find
, then yes, I would suggest you to write specific code for these containers. It is the most effective you can do.
template<typename ... Args> struct has_find {};
template<typename T> struct has_find<std::vector<T> > { static const bool value=false; };
template<typename T> struct has_find<std::deque<T> > { static const bool value=false; };
template<typename T, size_t I> struct has_find<std::array<T, I> > { static const bool value=false; };
template<typename T, typename U> struct has_find<std::map<T, U> > { static const bool value=true; };
//... and so on for the handful remaining containers
template<bool has_find>
struct contains_impl
{
template <typename C, typename E>
bool contains(const C& container, E&& element) const
{
return container.find(std::forward<E>(element)) != container.end();
}
};
template<>
struct contains_impl<false>
{
template <typename C, typename E>
bool contains(const C& container, E&& element) const
{
return std::find(container.cbegin(), container.cend(), std::forward<E>(element)) != container.cend();
}
};
template <typename C, typename E>
bool contains(const C& container, E&& element)
{
return contains_impl<has_find<C>::value>().contains(container, std::forward<E>(element));
}
The alternative would be to use metaprogramming and let the compiler determine whether the class contains a specific find
function, but that would maybe be a bit overkill...
Anyways, if want to go this way, you can read the recipes in this thread.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With