如何在函数参数中强制执行类型并避免隐式转换?

How to enforce type in function params and avoid implicit conversion?

我有一个功能

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();
}

是否有禁止此函数隐式转换的选项?

此代码编译失败:

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

在这个 post How do I avoid implicit conversions on non-constructing functions? 中,他们完全删除了某些类型的使用,但事实并非如此。

谢谢。

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();
}

您可以在函数中添加第二个模板参数和一个 static_assert 以确保第二个参数与容器的值类型完全相同。

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
}

完整示例 here.

在C++20中,就这么简单:

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();
}

在这段代码中std::same_as是一个概念,可以与简洁的模板语法一起使用。

此解决方案的一个优点是编译器错误发生在调用站点,告诉用户参数类型错误。