On 5 April 2013 21:12, François Dumont wrote: > > In fact my first attempt was a very simple one: > > template<typename _From, typename _To> > class __is_convertible_helper<_From, _To, false> > { > template<typename _To1> > static true_type > __test(_To1); > > template<typename> > static false_type > __test(...); > > public: > typedef decltype(__test<_To>(std::declval<_From>())) type; > }; > > But some tests failed like: > In file included from > /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/move.h:57:0, > from > /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/bits/stl_pair.h:59, > from > /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/utility:70, > from > /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/tuple:38, > from > /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/functional:55, > from > /home/fdt/dev/gcc/src/libstdc++-v3/testsuite/20_util/bind/38889.cc:23: > /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/type_traits: > In instantiation of 'struct std::__is_convertible_helper<const > std::tuple<std::_Placeholder<1> >&, std::_Placeholder<1>, false>': > /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/type_traits:1321:12: > required from 'struct std::is_convertible<const > std::tuple<std::_Placeholder<1> >&, std::_Placeholder<1> >' > /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/type_traits:111:12: > required from 'struct std::__and_<std::is_convertible<const > std::tuple<std::_Placeholder<1> >&, std::_Placeholder<1> > >' > /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/tuple:400:40: > required from 'struct std::_Bind<void (*(std::_Placeholder<1>))(int)>' > /home/fdt/dev/gcc/src/libstdc++-v3/testsuite/20_util/bind/38889.cc:28:41: > required from here > /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/type_traits:1316:30: > error: 'std::_Placeholder<1>' is an inaccessible base of > 'std::tuple<std::_Placeholder<1> >' > typedef decltype(__test<_To>(std::declval<_From>())) type; > ^ > /home/fdt/dev/gcc/build/x86_64-unknown-linux-gnu/libstdc++-v3/include/type_traits:1309:2: > error: initializing argument 1 of 'static std::true_type > std::__is_convertible_helper<_From, _To, false>::__test(_To1) [with _To1 = > std::_Placeholder<1>; _From = const std::tuple<std::_Placeholder<1> >&; _To > = std::_Placeholder<1>; std::true_type = std::integral_constant<bool, > true>]' > __test(_To1); > ^ > > From my point of view this is an other example of use case for which gcc is > not SFINAE friendly enough, no ?
No, I don't think this is a GCC problem. In this code the derived-to-base conversion does not happen in the context of the function template argument deduction but happens afterwards, so the access failure is not part of argument deduction and so is a hard error not a substitution failure. > But the version with the default template parameter is fine and more > consistent with the other helpers implementation so, adopted! Here is an > other version of the patch for validation. > > Daniel, I agree that inheritance with integral_constant is not as > obvious as before but it is still there and it is just what the compiler > need. I assume Daniel's reply was an HTML mail and didn't make it to the list, was there an objection to the change or a general comment? > I even hope that it also simplified a (very) little bit the job for > the compiler. I don't know if the compiler's job is easier or not, but I think with your change the template instantiation depth is increased by one, with your change we get false_type instantiated by the instantiation of is_convertible, rather than being done after it using its value member. > Ok to commit ? I'd like to hear Daniel's comment first, but if we don't hear from him please commit it in 24 hours. Thanks.