2017-11-04 3 views
4

std::minを関数に渡すことはコンパイルされません。 std::minのlibcpp宣言を私のソースファイルにコピーしています。関数std :: minを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; 
} 

打ち鳴らすと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

この関数は、1つのテンプレートパラメータに対してオーバーロードされます。 –

+1

エラーメッセージが表示されるのは、すでに何が間違っているかがわかります。 – hvd

+1

そして、どうしたの? – Quentin

答えて

7

つのテンプレートパラメータにオーバーロードされた2つのテンプレート関数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を使用してください。

3

あなたはこのように、ラムダでstd::minをラップすることができます:それが原因テンプレート引数のあいまいさのラムダラッパーなしでは動作しません

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

、説明だけでモスクワから@Vladのように。

関連する問題