4

I have a function

template<typename T>
static inline bool Contains(T container, const typename T::value_type& value)
{
    return std::find(container.begin(), container.end(), value) != container.end();
}

Is there an option to disallow implicit conversions for this function?

This code should fail compilation:

std::vector<int> vec = {1, 2, 3};
Contains(vec, -5.2);

In this post How do I avoid implicit conversions on non-constructing functions? they totally remove the use of some types, which is not the case.

Thanks.

joepol
  • 744
  • 6
  • 22

3 Answers3

5

In C++20, it would be as simple as this:

template<typename T>
static inline bool Contains(T container, std::same_as<typename T::value_type> auto const& value)
{
    return std::find(container.begin(), container.end(), value) != container.end();
}

In this code std::same_as is a concept, and can be used with the terse template syntax.

One advantage with this solution is that the compiler error happen at the call site, telling the user that the type of the parameter is wrong.

Guillaume Racicot
  • 39,621
  • 9
  • 77
  • 141
  • It's a great option! Specifically in this case if I could use C++20, most of the containers already implement `contains()` – joepol Jan 30 '21 at 17:49
4

You could add a second template parameter and a static_assert in the function to make sure that second parameter is exactly of the same type as the container's value type.

template<typename T, typename U>
static inline bool Contains(const T& container, const U& value)
{   
    static_assert(std::is_same_v<typename T::value_type, U>, "NO IMPLICIT CONVERSION ALLOWED");
    return std::find(container.begin(), container.end(), value) != container.end();
}

int main() {
    std::vector<int> vec = {1, 2, 3};
    Contains(vec, -5.2);  // Fails now
}

Full example here.

florestan
  • 4,405
  • 2
  • 14
  • 28
1
template<typename x_Container, typename x_Value>
static inline bool Contains(x_Container const & container, x_Value const & value)
{
    static_assert(::std::is_same_v<typename x_Container::value_type, x_Value>);
    return std::find(container.begin(), container.end(), value) != container.end();
}
user7860670
  • 35,849
  • 4
  • 58
  • 84