[libc++] c++14 return type deduction usage should be limited

Hi, hackers:

I noticed that in include/functional:

   _LIBCPP_INLINE_VISIBILITY auto operator()(_T1&& __t, _T2&& __u) const

is widely used to support C++14 type deduced function objects:

  ISO/IEC JTC1/SC22/WG21 N3421

However, in the standard text, the return type is specified with

  -> decltype(std::forward<T>(t) + std::forward<U>(u));

There is a slight difference between using return type deduction and
writing `decltype` out explicitly, because the later case triggers
SFINAE, while the first case does not. See:

  Return type deduction for normal functions


    Since the return type is deduced by instantiating the template, if the
    instantiation is ill-formed, this causes an error rather than a
    substitution failure. [...]"

I suggest to obey the standard here, even such a behavior may
(arguably) not be intentional.

BTW, in the adopted text, each of the new type deduced function
class has a `is_transparent` typedef, so...

function_objs_1y.2.patch (6.72 KB)

Well, crud.
I did that - and I left those bits off because I convinced myself that the two formulations were the same.

I can apply your patch if you would like - but do you have any ideas for writing test cases?

-- Marshall

Marshall Clow Idio Software <mailto:mclow.lists@gmail.com>

A.D. 1517: Martin Luther nails his 95 Theses to the church door and is promptly moderated down to (-1, Flamebait).
        -- Yu Suzuki

Well, maybe we should place some tests for std::result_of first :slight_smile:

Anyway, I'm sorry that I don't have the latest clang, so...

The `is_transparent` should be trivial, just -- does it worth?

I'd like to hold off on the is_transparent until we get a full implementation of N3657. Only then will we know for sure what unspecified type we really want is_transparent to be. And if we put it in prior to that as some other type, it is possible we will needlessly break someone's code.


I'm pretty sure that the typedef is nothing but a tag for SFINAE.
You can take a look at the file attached, which works with
my patch applied. And you consider to use it in libc++ tests
if we plan to merge the patch :slight_smile:

a.cc (1.32 KB)

Excuse me? Any responses on this?

Marshall checked in is_transparent yesterday in r188241 with an implementation of N3657 fro set and multiset.

I've been looking for an example that detects the lack of explicit return type on the functors and haven't found one yet. Do you have one? If it isn't detectable, then what is there is ok under the "as if" rule.


The file I attached before. Let me attach it here again.

a.cc (1.32 KB)

This test passes for me with:

totclang++ -std=c++1y -stdlib=libc++


/usr/local/bin/clang++ -Wall -stdlib=libc++ -std=c++1y
-I/home/lichray/devel/libcxx/include a.cc
a.cc:33:10: error: cannot initialize return object of type 'typename
      std::common_type<unsigned char, unsigned char>::type' (aka
'unsigned char') with
      an rvalue of type 'auto'
                return FunctorType::operator()(t...);
a.cc:58:43: note: in instantiation of function template specialization

::operator()<unsigned char,

      unsigned char>' requested here
        assert(stdex::operation<std::bit_xor<>>()(a, b) == 'L');
/usr/include/assert.h:54:21: note: expanded from macro 'assert'
#define assert(e) ((e) ? (void)0 : __assert(__func__, __FILE__, \
1 error generated.

clang++ r182968. If it's a clang bug, I have to install clang again
and try construct another test.

/usr/local/bin/clang++ -Wall -stdlib=libc++ -std=c++1y
-I/home/lichray/devel/libcxx/include a.cc
a.cc:33:10: error: cannot initialize return object of type 'typename
      std::common_type<unsigned char, unsigned char>::type' (aka
'unsigned char') with
      an rvalue of type 'auto'

This was a clang bug. There's no such thing as "an rvalue of type 'auto'".