无法将std::min传递给函数,std::min的副本可行

6
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'

1
该函数对一个模板参数进行了重载。 - Vlad from Moscow
1
你得到的错误信息看起来已经告诉你出了什么问题。 - user743382
1
请问出现了什么错误? - Quentin
问题附加了错误。 - tamas.kenez
2个回答

10

有两个针对一个模板参数重载的模板函数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


4
您可以像这样将std::min封装在一个lambda中:
std::thread thr1([](int a, int b) { return std::min(a, b); }, 2, 3);

没有Lambda包装器,由于模板参数的歧义,它无法工作,就像莫斯科的Vlad所解释的那样。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接