【问题标题】:Can't pass std::min to function, copy of std::min works无法将 std::min 传递给函数,std::min 的副本有效
【发布时间】:2017-11-04 09:31:40
【问题描述】:

std::min 传递给函数不会编译。我将 std::min 的 libcpp 声明复制到我的源文件中,它可以工作。

std 版本有什么问题? clang 和 gcc 也是如此。在 Godbolt 上测试:https://godbolt.org/g/zwRqUA

#include <thread>
#include <algorithm>

namespace mystd {
    // declaration copied verbatim from std::min (libcpp 4.0)
    template <class _Tp> inline constexpr const _Tp&
    mymin(const _Tp& __a, const _Tp& __b)
    {
        return std::min(__a, __b);
    }
}

int main()
{
    std::thread thr1(std::min<int>, 2, 3); // compile error
    std::thread thr2(mystd::mymin<int>, 2, 3); // works
    return 0;
}

clang 和 gcc 的错误:

[x86-64 clang 5.0.0 #1] error: no matching constructor for initialization of 'std::thread'

[x86-64 gcc 7.2 #1] error: no matching function for call to 'std::thread::thread(<unresolved overloaded function type>, int, int)'
[x86-64 gcc 7.2 #1] note:   couldn't deduce template parameter '_Callable'

【问题讨论】:

  • 函数被一个模板参数重载。
  • 您收到的错误消息在我看来已经告诉您出了什么问题。
  • 请问是什么错误?
  • 问题附加错误。

标签: c++ templates overloading overload-resolution


【解决方案1】:

为一个模板参数重载了两个模板函数min。他们是

template<class T> constexpr const T& min(const T& a, const T& b);

template<class T>
constexpr T min(initializer_list<T> t);

所以编译器不知道选择哪一个。

您可以使用函数指针的显式转换来告诉编译器您指的是哪个函数。

或者您可以使用中间指针。例如

const int & ( *operation )( const int &, const int & ) = std::min<int>;

然后用指针operation代替函数std::min

【讨论】:

    【解决方案2】:

    您可以将 std::min 包装在 lambda 中,如下所示:

    std::thread thr1([](int a, int b) { return std::min(a, b); }, 2, 3);
    

    由于模板参数不明确,没有 lambda 包装器就无法工作,就像来自莫斯科的 @Vlad 解释的那样。

    【讨论】:

      猜你喜欢
      • 2018-01-01
      • 2017-01-16
      • 1970-01-01
      • 1970-01-01
      • 2011-08-02
      • 1970-01-01
      • 2021-04-25
      • 2019-05-05
      • 2017-03-22
      相关资源
      最近更新 更多