This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [patch] [C++14] Implement N3657: heterogeneous lookup in associative containers.
- From: Jonathan Wakely <jwakely at redhat dot com>
- To: François Dumont <frs dot dumont at gmail dot com>
- Cc: libstdc++ at gcc dot gnu dot org, gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: Sat, 24 Jan 2015 22:46:53 +0000
- Subject: Re: [patch] [C++14] Implement N3657: heterogeneous lookup in associative containers.
- Authentication-results: sourceware.org; auth=none
- References: <20150119171608 dot GM3360 at redhat dot com> <20150120120015 dot GU3360 at redhat dot com> <54C0287C dot 5020502 at gmail dot com> <20150122020727 dot GJ3360 at redhat dot com> <54C416CD dot 4010907 at gmail dot com>
On 24/01/15 23:03 +0100, François Dumont wrote:
Sorry, I hadn't notice the condition to expose the new methods. It was
hidden within the _Rb_tree type that I hadn't check (and I do not
often check the Standard directly for my limited patches).
On my side I am surprised you didn't reuse your code to detect member
That adds another class template to the global namespace. I did that
initially, but (because I forgot about Debug + Profile modes) decided
against defining a new global type that is only needed in one place.
(N.B. _GLIBCXX_HAS_NESTED_TYPE is not mine, I only modified it
recently to use __void_t when I added that. Personally I find directly
using void_t is simpler than defining a new type using void_t and then
using that. I expect that to be the idiomatic solution in C++17 when
std::void_t is added.
types. I am also surprised that it is not using enable_if, IMHO it
makes the code clearer.
It doesn't work though.
@@ -1155,9 +1150,8 @@
return _S_iter(__y);
}
- template<typename _Kt,
- typename _Req = typename __is_transparent<_Compare, _Kt>::type>
- iterator
+ template<typename _Kt>
+ enable_if_t<__has_is_transparent<_Compare>::value, iterator>
_M_find_tr(const _Kt& __k)
This doesn't work.
Consider:
#include <set>
struct I
{
int i;
operator int() const { return i; }
};
int main()
{
std::set<int> s;
I i = { };
s.find(i);
}
(I will add something like this to the testsuite.)
This program is valid according to any C++ standard, but fails to
compile with your patch applied because overload resolution
instantiates std::_Rb_tree<>::_M_find_tr<I> which instantiates
enable_if<false, iterator>::type, which is an error. SFINAE does not
apply, because the invalid type enable_if<false, iterator>::type is
not found during *substitution*. It's just invalid, so when _Compare
is not transparent, instantiating the function template is simply an
error.
Observe that my __is_transparent alias template takes two template
arguments, so that it depends on the template parameter of the
function, not only on _Compare. That means whether if the type is
invalid that will be found during template argument substitution, so
SFINAE applies.