[patch] [C++14] Implement N3657: heterogeneous lookup in associative containers.

Jonathan Wakely jwakely@redhat.com
Sat Jan 24 22:46:00 GMT 2015


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.



More information about the Libstdc++ mailing list