自动变量可存储函数指针到std :: max

Auto variable to store function pointer to std::max

本文关键字:std 指针 max 函数 变量 存储      更新时间:2023-10-16

我正在尝试将函数std::max作为模板参数传递到模板函数,但由于某些原因,编译器打印错误的错误无法推导函数类型。一个简单的示例复制了同一问题。它可以使用自己的max2函数,但不适用于STL std::max

#include <algorithm>
template <class T>
T max2(const T& a, const T& b) { return std::max(a, b); }
int main() {
#if 1
  auto f = max2<float>;
#else
  // error: unable to deduce ‘auto’ from ‘max<float>’
  auto f = std::max<float>;
#endif
  float max_val = f(1.0f, 2.0f);
  return 0;
}

如下所示, std::max<float>不是一个明确的函数。此时,这是一个过载组,仍然有两种可能性:

constexpr const float& max( const float& a, const float& b );
constexpr float max( std::initializer_list<float> ilist );

您有两个主要选择:

  1. 将其包裹在lambda中:

     auto f = [](float a, float b) { return std::max(a, b); };
     // Note there's no by-reference behaviour in this lambda.
    
  2. 如果您想要更可重复使用的东西,则需要单独包装,例如,不需要恶作剧来传播的东西:

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

显然#2带有重要的样板,这忽略了其他过载和constexpr。将来,预计您将能够做得更好。今天,您可以用宏来模仿这样的东西(最简单地使宏扩展到lambda)。我遇到了至少一个LIFT宏。

有一个第三个选项可以吸引人,因为它是一行(一条丑陋的行,但一行),并且铸造为正确的功能指针类型。但是,这是不允许的,除了在几个特殊情况下[namespace.std]/6。