使用 std::initializer_list 使函数指针指向 std::min

Make function pointer to std::min with std::initializer_list

我想制作一个函数指针并在构造函数中初始化它。

如果 type_ 是 Min,找到所有输入的最小值。

如果 type_ 是 Max,找到所有输入的最大值。

我写下了下面的代码,但是在VS 2014中无法编译,C++编译器版本是MSVC 19.0.23506.0。

uint32_t (*compare) (std::initializer_list<const uint32_t> init_list);

if (Min == type_) {
  compare = std::min<std::initializer_list<const uint32_t>>;
} else if (Max == type_) {
  compare = std::max<std::initializer_list<const uint32_t>>;
}

错误如下:

error C2563: mismatch in formal parameter list
error C2568: '=': unable to resolve function overload
note: could be '_Ty std::min(std::initializer_list<_Elem>,_Pr)'
note: or       'const _Ty &std::min(const _Ty &,const _Ty &,_Pr)'
note: or       '_Ty std::min(std::initializer_list<_Elem>)'
note: or       'const _Ty &std::min(const _Ty &,const _Ty &)'

似乎是类型不匹配,但我不知道如何解决。

但是,如果您使用现代 C++ 机制有更优雅的解决方案。 很高兴看到这一点!

从 C++14 开始,std::min 的重载如下:

template <class T> constexpr const T& min(const T&, const T&); // (1)
template <class T, class Compare> constexpr const T& min(const T&, const T&, Compare); // (2)
template <class T> constexpr T min(std::initializer_list<T> ); // (3)
template <class T, class Compare> constexpr T min(std::initializer_list<T>, Compare ); // (4)

其中两个只有一个模板参数:(1)(需要两个 const T&)和 (3)(需要一个 std::initializer_list<T>)。您想要的是 (3) - 但请注意它的模板参数是 只是 T... 而不是 std::initializer_list<T>。出现编译器错误是因为您指定了错误的模板函数 - 并且两个可能的单模板参数重载都不能分配给 compare.

所以只需修改您指定的方式即可:

// not const... just initializer_list<uint32_t>
uint32_t (*compare) (std::initializer_list<uint32_t>);

// select the correct overload
compare = std::min<uint32_t>;

这是有效的,因为虽然仍然有两个名为 std::min<uint32_t> 的重载((1)(3)),但实际上只有 (3) 可以转换为 uint32_t(*)(std::initializer_list<uint32_t>) .