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?
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.
Related
I need a 'MultiStack' taking different types of objects, putting each type in a separate stack.
This is what it looks like so far. The open problem is: how to handle the containers for a number of different T
class MultiStack
{
public:
template<typename T>
const T& Get()
{
return Container<T>.back();
}
template<typename T>
void Push( const T& t )
{
Container<T>.push_back( t );
}
template<typename T>
void Pop( const T& /*t*/ )
{
Container<T>.pop_back();
}
private:
// this does not make sense, we obv. need one stack for each T
// template<typename T>
// std::vector<T> Container;
};
Now, I could use the old trick, putting the Container in a member function, like
template<typename T>
auto GetContainer()
{
static std::vector<T> C;
return C;
}
but I don't like this anymore in the age of multi-threading. It is 'dangerous', right!?
Is there a better, elegant way? It is conceivable that I know the allowed types beforehand, if that helps realizing it.
but I don't like this anymore in the age of multi-threading. It is 'dangerous', right!?
Issue is not multi-threading. initialization would be fine.
You still have to protect/synchronize access though, as regular multi-threading code.
Issue is that the container is not per instance of MultiTask, as it is static.
It is mostly as if MultiTask were a Singleton.
It is conceivable that I know the allowed types beforehand, if that helps realizing it.
That helps, you can then use std::tuple, something like (C++14):
template <typename ... Ts>
class MultiStack
{
public:
template<typename T>
const T& Get() const
{
return GetContainer<T>().back();
}
template<typename T>
void Push(const T& t)
{
GetContainer<T>().push_back(t);
}
template <typename T>
void Pop()
{
GetContainer<T>().pop_back();
}
private:
template <typename T>
const std::vector<T>& GetContainer() const { return std::get<std::vector<T>>(Containers); }
template <typename T>
std::vector<T>& GetContainer() { return std::get<std::vector<T>>(Containers); }
private:
std::tuple<std::vector<Ts>...> Containers;
};
I thought this std::map key extraction into an std::vector should have worked without specifying --std=c++0x flag for gcc (4.6), but it did not. Any idea why?
template <typename Map, typename Container>
void extract_map_keys(const Map& m, Container& c) {
struct get_key {
typename Map::key_type operator()
(const typename Map::value_type& p) const {
return p.first;
}
};
transform(m.begin(), m.end(), back_inserter(c), get_key());
}
Thanks!
The reason is that you are using a local type get_key as the last argument. This was not allowed in C++98 and the rules have been changed/relaxed for C++11.
This can be seen in this example:
template <class T> bool cpp0X(T) {return true;} //cannot be called with local types in C++03
bool cpp0X(...){return false;}
bool isCpp0x()
{
struct local {} var;
return cpp0X(var);
}
With n different classes, which should all be comparable with operator== and operator!=, it would be necessary to implement (n ^ 2 - n) * 2 operators manually. (At least I think that's the term)
That would be 12 for three classes, 24 for four. I know that I can implement a lot of them in terms of other operators like so:
operator==(A,B); //implemented elsewhere
operator==(B,A){ return A == B; }
operator!=(A,B){ return !(A == B); }
but it still seems very tedious, especially because A == B will always yield the same result as B == A and there seems to be no reason whatsoever to implement two version of them.
Is there a way around this? Do I really have to implement A == B and B == A manually?
Use Boost.Operators, then you only need to implement one, and boost will define the rest of the boilerplate for you.
struct A
{};
struct B : private boost::equality_comparable<B, A>
{
};
bool operator==(B const&, A const&) {return true;}
This allows instances of A and B to be compared for equality/inequality in any order.
Live demo
Note: private inheritance works here because of the Barton–Nackman trick.
In the comments the problem is further explained by stating that all of the types are really different forms of smart pointers with some underlying type. Now this simplifies quite a lot the problem.
You can implement a generic template for the operation:
template <typename T, typename U>
bool operator==(T const & lhs, U const & rhs) {
return std::addressof(*lhs) == std::addressof(*rhs);
}
Now this is a bad catch all (or rather catch too many) implementation. But you can narrow down the scope of the operator by providing a trait is_smart_ptr that detects whether Ptr1 and Ptr2 are one of your smart pointers, and then use SFINAE to filter out:
template <typename T, typename U,
typename _ = typename std::enable_if<is_pointer_type<T>::value
&& is_pointer_type<U>::value>::type >
bool operator==(T const & lhs, U const & rhs) {
return std::addressof(*lhs) == std::addressof(*rhs);
}
The type trait itself can be just a list of specializations of a template:
template <typename T>
struct is_pointer_type : std::false_type {};
template <typename T>
struct is_pointer_type<T*> : std::true_type {};
template <typename T>
struct is_pointer_type<MySmartPointer<T>> : std::true_type {};
template <typename T>
struct is_pointer_type<AnotherPointer<T>> : std::true_type {};
It probably makes sense not to list all of the types that match the concept of pointer, but rather test for the concept, like:
template <typename T, typename U,
typename _ = decltype(*declval<T>())>
bool operator==(T const & lhs, U const & rhs) {
return std::addressof(*lhs) == std::addressof(*rhs);
}
Where the concept being tested is that it has operator* exists. You could extend the SFINAE check to verify that the stored pointer types are comparable (i.e. that std::addressof(*lhs) and std::addressof(*rhs) has a valid equality:
template <typename T, typename U,
typename _ = decltype(*declval<T>())>
auto operator==(T const & lhs, U const & rhs)
-> decltype(std::addressof(*lhs) == std::addressof(*rhs))
{
return std::addressof(*lhs) == std::addressof(*rhs);
}
And this is probably as far as you can really get: You can compare anything that looks like a pointer to two possibly unrelated objects, if raw pointers to those types are comparable. You might need to single out the case where both arguments are raw pointers to avoid this entering out into a recursive requirement...
not necesarily:
template<class A, class B>
bool operator==(const A& a, const B& b)
{ return b==a; }
works for whatever A and B there is a B==A implementation (otherwise will recourse infinitely)
You can also use CRTP if you don't want the templetized == to work for everything:
template<class Derived>
class comparable {};
class A: public comparable<A>
{ ... };
class B: public comparable<B>
{ ... };
bool operator==(const A& a, const B& b)
{ /* direct */ }
// this define all reverses
template<class T, class U>
bool operator==(const comparable<T>& sa, const comparable<U>& sb)
{ return static_cast<const U&>(sb) == static_cast<const T&>(sa); }
//this defines inequality
template<class T, class U>
bool operator!=(const comparable<T>& sa, const comparable<U>& sb)
{ return !(static_cast<const T&>(sa) == static_cast<const U&>(sb)); }
Using return type SFINAE yo ucan even do something like
template<class A, class B>
auto operator==(const A& a, const B& b) -> decltype(b==a)
{ return b==a; }
template<class A, class B>
auto operator!=(const A& a, const B& b) -> decltype(!(a==b))
{ return !(a==b); }
The goal here is to deal with large n reasonably efficiently.
We create an order, and forward all comparison operators to comp after reordering them to obey that order.
To do this, I start with some metaprogramming boilerplate:
template<class...>struct types{using type=types;};
template<class T,class types>struct index_of{};
template<class T,class...Ts>struct index_of<T,types<T,Ts...>>:
std::integral_constant<unsigned,0>
{};
template<class T,class U,class...Us>struct index_of<T,types<U,Us...>>:
std::integral_constant<unsigned,1+index_of<T,types<Us...>>::value>
{};
which lets us talk about ordered lists of types. Next we use this to impose an order on these types:
template<class T, class U,class types>
struct before:
std::integral_constant<bool, (index_of<T,types>::value<index_of<U,types>::value)>
{};
Now we make some toy types and a list:
struct A{}; struct B{}; struct C{};
typedef types<A,B,C> supp;
int comp(A,B);
int comp(A,C);
int comp(B,C);
int comp(A,A);
int comp(B,B);
int comp(C,C);
template<class T,class U>
std::enable_if_t<before<T,U,supp>::value, bool>
operator==(T const& t, U const& u) {
return comp(t,u)==0;
}
template<class T,class U>
std::enable_if_t<!before<T,U, supp>::value, bool>
operator==(T const& t, U const& u) {
return comp(u,t)==0;
}
template<class T,class U>
std::enable_if_t<before<T,U,supp>::value, bool>
operator<(T const& t, U const& u) {
return comp(t,u)<0;
}
template<class T,class U>
std::enable_if_t<!before<T,U, supp>::value, bool>
operator<(T const& t, U const& u) {
return comp(u,t)>0;
}
etc.
The basic idea is that supp lists the types you want to support, and their prefered order.
Boilerplate operators then forward everything to comp.
You need to implement n*(n-1)/2 comps to handles each pair, but only in one order.
Now for the bad news: probably you want to lift each type to some common type and compare there, rather than het lost in the combinatorial morass.
Suppose you can define a type Q which can store the imformation required to sort any of them.
Then write convert-to-Q code from each type, and implement comparison on Q. This reduces the code written to O(a+b), where a is the number of types and b the number of operators supported.
As an example, smart pointers can be pointer-ordered between each other this way.
Context: C++03 only + the use of boost is authorized
I'd like to raise the same question as in
How to negate a predicate function using operator ! in C++?
... but with an overloaded boolean predicate, that is:
struct MyPredicate
{
bool operator()(T1) const;
bool operator()(T2) const;
};
Clearly, MyPredicate cannot be derived from std::unary_function as it is impossible to define a single argument_type.
The aim is to use MyPredicate as argument to range adaptors, with a readable syntax like this:
using boost::for_each;
using boost::adaptors::filtered;
list<T1> list1;
list<T2> list2;
for_each(list1 | filtered(!MyPredicate()), doThis);
for_each(list2 | filtered(!MyPredicate()), doThat);
Of course, any solution involving explicit disambiguation is of no interest here.
Thank you in advance.
[ACCEPTED SOLUTION]
I'm using a slightly modified version of Angew's solution:
template <class Predicate>
struct Not
{
Predicate pred;
Not(Predicate pred) : pred(pred) {}
template <class tArg>
bool operator() (const tArg &arg) const
{ return !pred(arg); }
};
template <class Pred>
inline Not<Pred> operator! (const Pred &pred)
{
return Not<Pred>(pred);
}
template <class Pred>
Pred operator! (const Not<Pred> &pred)
{
return pred.pred;
}
Note that operators && and || can benefit from this trick likewise.
You can do this:
struct MyPredicate
{
bool positive;
MyPredicate() : positive(true) {}
bool operator() (T1) const {
return original_return_value == positive;
}
bool operator() (T2) const {
return original_return_value == positive;
}
};
inline MyPredicate operator! (MyPredicate p) {
p.positive = !p.positive;
return p;
}
To address your concern of forgetting to use positive, you could try an alternative approach with a wrapper class.
template <class Predicate>
struct NegatablePredicate
{
Predicate pred;
bool positive;
NegatablePredicate(Predicate pred, bool positive) : pred(pred), positive(positive) {}
template <class tArg>
bool operator() (const tArg &arg) const
{ return pred(arg) == positive; }
};
template <class Pred>
inline NegatablePredicate<Pred> operator! (const Pred &pred)
{
return NegatablePredicate<Pred>(pred, false);
}
You can also add an overload for optimisation purposes:
template <class Pred>
inline NegatablePredicate<Pred> operator! (const NegatablePredicate<Pred> &pred)
{
return NegatablePredicate<Pred>(pred.pred, !pred.positive);
}
To address possible concern with the wide scope of the template operator!, you can employ boost::enable_if magic.
You actually can derive from std::unary_function:
template<typename T>
struct MyPredicate : std::unary_function<T, bool>
{
bool operator()(T) const;
};
I want to write my own algorithm (just a function really) that takes a range of iterators. If the iterators are from a map, I want to use the data (iterator->second) value. If the iterator is "normal" like a vector or list, I just want to use the dereferenced iterator value.
I think, value-getter idea is right here, but you can implement it without c++11 and without structs at all, only using functions:
template <typename T>
const T& get(const T& t)
{
return t;
}
template <typename T, typename V>
const V& get(const std::pair<T,V>& t)
{
return t.second;
}
int main()
{
std::vector<int> v = {1};
std::cout << get(*v.begin());
std::cout << "\n----\n";
std::map<int, std::string> m;
m.insert(std::make_pair(0, "sss"));
std::cout << get(*m.cbegin());
}
You can make a value-getter class that extracts the value you're interested in. Note that this approach doesn't work if you store pairs in any container (it transforms all pairs, whether in a map or not). I'd think it would be a much clearer approach to only accept "regular" iterators and let it be callers job to transform map iterators appropriately (as suggested in the comments to your question.)
template<typename T>
struct get {
static auto val(const T& t) -> const T&
{
return t;
}
};
template<typename U, typename V>
struct get<std::pair<U, V>> {
static auto val(const std::pair<U, V>& p) -> const V&
{
return p.second;
}
};
// use like
get<decltype(*iter)>::val(*iter);
Convenience function could look like:
template<class T>
auto getval(const T& t) -> decltype(get<T>::val(t))
{
return get<T>::val(t);
}
You can overload the function based on the input:
void foo(const std::vector<int>::iterator& it1, const std::vector<int>::iterator& it2)
{
//use *it
}
void foo(const std::map<int,int>::iterator& it1, const std::map<int,int>::iterator& it2)
{
//use it->second
}
Edit:
I think this is the closest you can get to what you want to achieve:
template <typename T, typename X>
void foo(T const& x, X const& y)
{
}
template <typename T, typename S>
void foo(const typename std::map<T,S>::iterator& x, const typename std::map<T,S>::iterator& y)
{
}
int main()
{
std::map<int,int> x;
std::vector<int> y;
foo(x.begin(), x.end()); //will call second version
foo(y.begin(), y.end()); //will call first version
}
A trait should do the trick. First the type-deducing helper:
template <typename Iter>
typename iter_value<Iter>::value_type & iter_deref(Iter it)
{
return iter_value<Iter>::deref(it);
}
All we need is something like this:
template <typename Iter>
class iter_value
{
template <typename T> struct aux
{
typedef T type;
static type & deref(Iter it) { return *it; }
};
template <typename U, typename V> struct aux<std::pair<U const, V>>
{
typedef V type;
static type & deref(Iter it) { return it->second; }
};
typedef typename std::iterator_traits<Iter>::value_type type;
public:
typedef typename aux<type>::type value_type;
static value_type & deref(Iter it)
{
return aux<type>::deref(it);
}
};
You can create a function that extracts the value out of the iterator. Then you can overload that based on the type of the iterator. You can use that function in your algorithm. Assuming a vector of ints and a map of string->int, it could look like this:
int getValue(const std::vector<int>::iterator& it)
{
return *it;
}
int getValue(const std::map<std::string, int>::iterator& it)
{
return it->second;
}
Then the algorithm can use the function getValue() to get a value from the iterator.