无法将std :: min传递给函数,std :: min的副本可以正常工作

tam*_*nez 5 c++ templates overloading overload-resolution

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

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;
}
Run Code Online (Sandbox Code Playgroud)

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'
Run Code Online (Sandbox Code Playgroud)

Vla*_*cow 8

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

template<class T> constexpr const T& min(const T& a, const T& b);
Run Code Online (Sandbox Code Playgroud)

template<class T>
constexpr T min(initializer_list<T> t);
Run Code Online (Sandbox Code Playgroud)

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

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

或者你可以使用中间指针.例如

const int & ( *operation )( const int &, const int & ) = std::min<int>;
Run Code Online (Sandbox Code Playgroud)

然后使用指针operation而不是函数std::min.