[cfe-dev] Compile error with libc++'s bind
Howard Hinnant
hhinnant at apple.com
Fri May 20 14:37:42 PDT 2011
On May 20, 2011, at 3:30 PM, Howard Hinnant wrote:
> On May 20, 2011, at 3:18 PM, Howard Hinnant wrote:
>
>> On May 20, 2011, at 2:59 PM, Jonathan Sauer wrote:
>>
>>> Hello,
>>>
>>> the following program fails to compile with clang trunk and libc++ trunk (note the implicit conversion from <const char*>
>>> to <std::string> when calling the functor in <doIt>):
>>>
>>> #include <functional>
>>>
>>> using namespace std::placeholders;
>>>
>>> template <typename Functor>
>>> static void doIt(Functor f)
>>> {
>>> f("");
>>> }
>>>
>>> static void method(const std::string&); // A
>>> //static void method(const char*); // B
>>>
>>> int main(int, char**)
>>> {
>>> doIt(std::bind(&method, _1));
>>> }
>>>
>>>
>>> This results in the following error:
>>>
>>> $ ~/LLVM/build/Release+Asserts/bin/clang -std=c++0x -stdlib=libc++ clang.cpp
>>> In file included from clang.cpp:1:
>>> /usr/include/c++/v1/functional:1620:8: error: no type named 'type' in 'std::__1::__invoke_of<void
>>> (*&)(const std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>
>>>> &), char const (&)[1]>'
>>>> ::type type;
>>>
>>>
>>> Commenting line (A) and uncommenting line (B), i.e. removing the implicit conversion, makes the code compile.
>>>
>>> I looked into the standard, section 20.8, but was unable to find anything about implicit conversions, although it seems to
>>> me from reading 20.8.2p1 that they should be allowed.
>>>
>>> A similar code used to compile with an older version of libc++ (most likely before Howard's implementations in r131639ff.
>>>
>>> So my question is: Is this a bug in libc++, or are implicit conversions not allowed, and the similar code used to compile
>>> because of an implementation artefact that was removed during r131639ff?
>>
>> This looks like a bug either in the new __invoke_of trait, or in clang's SFINAE / overload handling. Not sure yet. Investigating...
>
> At the very least we have a misleading error message:
>
> error: no type named 'type' in 'std::__1::__invoke_of<void (*&)(const std::__1::basic_string<char,
> std::__1::char_traits<char>, std::__1::allocator<char> > &), char const (&)[1]>'
>> ::type type;
> ~~~^~~~
>
> And yet:
>
> #include <type_traits>
> #include <string>
>
> static void method(const std::string&) {} // A
>
> #include <iostream>
>
> int main()
> {
> std::cout << std::__invokable<void (*&)(const std::string&), char const (&)[1]>::value << '\n';
> std::cout << typeid(std::__invoke_of<void (*&)(const std::string&), char const (&)[1]>::type).name() << '\n';
> }
>
> outputs:
>
> 1
> v
>
> Meaning std::__invoke_of<void (*&)(const std::string &), char const (&)[1]> >::type exists and has type void.
I've submitted this bugzilla:
http://llvm.org/bugs/show_bug.cgi?id=9975
Howard
More information about the cfe-dev
mailing list