使用 std::initializer_list 创建指向 std::min 的函数指针

Posted

技术标签:

【中文标题】使用 std::initializer_list 创建指向 std::min 的函数指针【英文标题】:Make function pointer to std::min with std::initializer_list 【发布时间】:2016-03-07 19:03:33 【问题描述】:

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

如果 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++ 机制有更优雅的解决方案。 很高兴看到这一点!

【问题讨论】:

你不需要使用const 类型,initializer_list 是不可变的 您可能希望在最终的else 案例中将compare 初始化为nullptr。至少当我看到这样的未初始化变量时我会发痒。 【参考方案1】:

以下是 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&amp;s)和(3)(需要一个std::initializer_list&lt;T&gt;)。你想要的是(3) - 但请注意它的模板参数只是T...不是std::initializer_list&lt;T&gt;。出现编译器错误是因为您指定了错误的模板函数 - 两个可能的单模板参数重载都不能分配给 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&lt;uint32_t&gt; 的重载((1)(3)),但实际上只有 (3) 可以转换为 uint32_t(*)(std::initializer_list&lt;uint32_t&gt;)

【讨论】:

解释很有帮助!

以上是关于使用 std::initializer_list 创建指向 std::min 的函数指针的主要内容,如果未能解决你的问题,请参考以下文章

为啥在使用大括号初始值设定项列表时首选 std::initializer_list 构造函数?

为啥 `std::initializer_list` 不提供下标运算符?

为啥 std::min(std::initializer_list<T>) 按值接受参数?

为啥 std::initializer_list 不是内置语言?

std::initializer_list 作为函数参数

如何将 C 数组转换为 std::initializer_list?