c++ - 在 C++11 中使用 max<int> 作为谓词中断

标签 c++ c++11 c++14

在 C++03 中,以下代码可以正常工作:

int main()
{
    std::vector<int> v;
    v.push_back(1);
    v.push_back(2);
    v.push_back(3);

    std::vector<int> v2;
    v2.push_back(2);
    v2.push_back(3);
    v2.push_back(4);

    std::transform(v.begin(), v.end(), v2.begin(), v2.begin(), std::max<int>);
    return 0;
}

在 C++11 中这不起作用,因为它为包含 initializer_liststd::max 添加了重载。因此,您必须使用非常丑陋的类型转换来选择正确的重载:

static_cast<const int& (*)(const int&, const int&)>(std::max)

我有几个问题。

  • 为什么标准委员会知道这样做会(可能)破坏现有代码并迫使用户创建丑陋的类型转换?
  • future 的 C++ 标准是否会尝试缓解这个问题?
  • 什么是解决方法?

最佳答案

如果您经常这样做,您可能需要编写一个透明仿函数包装器:

struct my_max {
    template<class T>
    const T& operator()(const T& a, const T& b) const{
        return std::max(a, b);
    }
};

那么你可以简单地做

std::transform(v.begin(), v.end(), v2.begin(), v2.begin(), my_max());

只要你需要它,而不是每次都编写 lambda 或强制转换。这与透明运算符仿函数的想法基本相同 - 让模板参数在实际调用位置推导出,而不是在创建仿函数时显式指定。

如果你想让这个更有趣,你甚至可以让 operator() 采用异构类型并添加完美转发并使用尾随返回类型:

struct my_max {
    template<class T, class U>
    constexpr auto operator()( T&& t, U&& u ) const
      -> decltype(t < u ? std::forward<U>(u) : std::forward<T>(t)){
        return t < u ? std::forward<U>(u) : std::forward<T>(t);
    }
};

在 C++14 中,这被简化为

struct my_max {
    template<class T, class U>
    constexpr decltype(auto) operator()( T&& t, U&& u ) const{
        return t < u ? std::forward<U>(u) : std::forward<T>(t);
    }
};

关于c++ - 在 C++11 中使用 max<int> 作为谓词中断,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26215437/

相关文章:

c++ - 使用 scanf 进行输入过滤

c++ - 如何检查 DLL 的信息

c++ - 定义前向输出迭代器的规范方式

c++ - SFINAE on Error in Dependent Type 导致意外的硬错误

c++ - 为什么不能使用 [[deprecated]] 弃用模板?

c++ - 在模板类中使用 'new' 是类型安全的吗?

c++ - select() 用于 UDP 连接

c++ - 如果我使用选项 -finit-local-zero 编译 Fortran,则 Fortran <-> C++ 互操作性的 Pb

c++ - 在数组大小中使用位操作的原因

c++ - 使用 make_unique 语句重新分配 unique_ptr 对象 - 内存泄漏?