Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

<functional>: std::is_convertible is broken for std::bind functors #952

Closed
AlexGuteniev opened this issue Jul 1, 2020 · 6 comments · Fixed by #3577
Closed

<functional>: std::is_convertible is broken for std::bind functors #952

AlexGuteniev opened this issue Jul 1, 2020 · 6 comments · Fixed by #3577
Labels
bug Something isn't working fixed Something works now, yay!

Comments

@AlexGuteniev
Copy link
Contributor

AlexGuteniev commented Jul 1, 2020

Describe the bug
std::is_convertible fails to compile broken for a lambda passed to std::bind

Command-line test case

D:\Temp2>type repro.cpp
#include <functional>
#include <iostream>

int main() {
    auto l = [](int) {};
    auto f = std::bind(l, std::placeholders::_1);
    std::cout << std::is_convertible<decltype(f), std::function<void()>>::value << std::endl;
}

D:\Temp2>cl /EHsc /W4 /WX .\repro.cpp
Microsoft (R) C/C++ Optimizing Compiler Version 19.27.29009.1 for x86
Copyright (C) Microsoft Corporation.  All rights reserved.

repro.cpp
c:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\utility(487): error C2338: tuple index out of bounds
c:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\functional(1371): note: see reference to class template instantiation 'std::tuple_element<0,std::tuple<>>' being compiled
c:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\tuple(672): note: see reference to alias template instantiation 'std::tuple_element_t<0,std::tuple<>>' being compiled
c:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\tuple(790): note: see reference to function template instantiation 'const tuple_element<_Index,std::tuple<_Rest...>>::type &&std::get(const std::tuple<_Rest...> &&) noexcept' being compiled
c:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\type_traits(1720): note: see reference to alias template instantiation 'std::_Decltype_invoke_zero<std::_Binder<std::_Unforced,main::<lambda_47bb48da0a3b46550689dee1f28f59ab> &,const std::_Ph<1> &>&>' being compiled
c:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\type_traits(1796): note: see reference to alias template instantiation 'std::_Is_invocable_r_<void,std::_Binder<std::_Unforced,main::<lambda_47bb48da0a3b46550689dee1f28f59ab> &,const std::_Ph<1> &>&,>' being compiled
c:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\functional(961): note: see reference to class template instantiation 'std::_Is_invocable_r<_Ret,_From &>' being compiled
        with
        [
            _Ret=void,
            _From=std::_Binder<std::_Unforced,main::<lambda_47bb48da0a3b46550689dee1f28f59ab> &,const std::_Ph<1> &>
        ]
c:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\functional(961): note: see reference to variable template 'const bool conjunction_v<std::negation<std::is_same<std::_Binder<std::_Unforced,<lambda_47bb48da0a3b46550689dee1f28f59ab> &,std::_Ph<1> const &>,std::function<void __cdecl(void)> > >,std::_Is_invocable_r<void,std::_Binder<std::_Unforced,<lambda_47bb48da0a3b46550689dee1f28f59ab> &,std::_Ph<1> const &> &> >' being compiled
c:\Program Files (x86)\Microsoft Visual Studio\2019\Preview\VC\Tools\MSVC\14.27.29009\include\utility(487): note: see reference to alias template instantiation 'std::_Func_class<_Ret>::_Enable_if_callable_t<_From&,std::function<void (void)>>' being compiled
        with
        [
            _Ret=void,
            _From=std::_Binder<std::_Unforced,main::<lambda_47bb48da0a3b46550689dee1f28f59ab> &,const std::_Ph<1> &>
        ]
.\repro.cpp(7): note: see reference to class template instantiation 'std::is_convertible<std::_Binder<std::_Unforced,main::<lambda_47bb48da0a3b46550689dee1f28f59ab> &,const std::_Ph<1> &>,std::function<void (void)>>' being compiled

Expected behavior
The program should compile.
(It should print zero, as the types are not expected to be convertible)

STL version

Microsoft Visual Studio Professional 2019 Preview
Version 16.7.0 Preview 3.1

Additional context
This item is also tracked on Developer Community as DevCom-317991 and by Microsoft-internal VSO-671111 / AB#671111.

@CaseyCarter CaseyCarter added the enhancement Something can be improved label Jul 1, 2020
@CaseyCarter
Copy link
Member

I'm tagging this "enhancement" rather than "bug" because the expected behavior is not Standard-mandated behavior so much as a desirable extension.

@AlexGuteniev
Copy link
Contributor Author

I don't understand why it is not Standard-mandated.

@StephanTLavavej
Copy link
Member

It's because nothing in bind()'s specification requires its function call operator to SFINAE away for un-callable arguments. (This is because bind() is ancient and predates result_of SFINAE.)

I'm 95% sure that this analysis is still correct. If the Standardese actually requires bind() to SFINAE, please let me know.

@timsong-cpp
Copy link
Contributor

timsong-cpp commented Jul 3, 2020

After WG21-P1065, bind's specification now uses expression-equivalent, which I think requires SFINAE?

@CaseyCarter
Copy link
Member

After WG21-P1065, bind's specification now uses expression-equivalent, which I think requires SFINAE?

Close enough to it, yes. So let's call this a bug.

@CaseyCarter CaseyCarter added bug Something isn't working and removed enhancement Something can be improved labels Jul 3, 2020
@StephanTLavavej
Copy link
Member

Oh yeah, I noticed expression-equivalent's conditional noexcept implication while reviewing #703 (which @AdamBucior then implemented), I should have realized it implies SFINAE too. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fixed Something works now, yay!
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants