【问题标题】:How to enforce type in function params and avoid implicit conversion?如何强制输入函数参数并避免隐式转换?
【发布时间】:2021-01-28 14:40:00
【问题描述】:

我有一个函数

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

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

谢谢。

【问题讨论】:

    标签: c++ templates implicit-conversion


    【解决方案1】:

    在 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 是一个概念,可以与简洁的模板语法一起使用。

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

    【讨论】:

    • 这是个不错的选择!特别是在这种情况下,如果我可以使用 C++20,大多数容器已经实现了contains()
    【解决方案2】:

    您可以在函数中添加第二个模板参数和 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

    【讨论】:

      【解决方案3】:
      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();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多