Paradox
Paradox

Reputation: 2035

Template conflict for similar numerical types

I have a very simple function

template<typename T>
bool is_element(const std::vector<T> & vec, T el)
{
    return (std::find(vec.begin(), vec.end(), el) != vec.end());
}

that is supposed to just check if an element exists in a vector. But I run into problems when for example el is an unsigned long and vec is an integer vector. The template types are different initially, but the same after implicit conversion. Is there any elegant way to deal incorporate implicit conversion into templates without doing a bunch of function overloading?

Upvotes: 0

Views: 95

Answers (3)

Jarod42
Jarod42

Reputation: 217810

You can make one parameter non deducible.

Following does that and also makes it more generic:

template <typename Container>
bool is_element(const Container& cont, const Container::value_type& e)
{
    return (std::find(cont.begin(), cont.end(), e) != cont.end());
}

Upvotes: 4

Igor R.
Igor R.

Reputation: 15075

You could deduce T using the first parameter, while suppressing type-deduction in the second one by putting it in a non-deducible context:

template<class T>
struct suppress_deduction {
    using type = T;
};

template<class T>
using suppress_deduction_t = typename suppress_deduction<T>::type;

template<typename T>
bool is_element(const std::vector<T> & vec, suppress_deduction_t<T> el)
{
    return (std::find(vec.begin(), vec.end(), el) != vec.end());
}

Upvotes: 5

robthebloke
robthebloke

Reputation: 9678

Do you need to limit yourself to a single template type?

template<typename T, typename S>
bool is_element(const std::vector<T> & vec, S el)
{
    return (std::find(vec.begin(), vec.end(), el) != vec.end());
}

Upvotes: 4

Related Questions