Open BengtGustafsson opened 1 year ago
This offers possibilities to bring templates and concepts into scope without having to repeat their template parameter lists:
template auto MT = ComplicatedNamespaceName::MyTemplate;
template auto DT = DependentClass::template MyTemplate; // Disambiguate dependent name once and for all!
template auto MC = ComplicatedNamespaceName::MyConcept;
Yes, as Gasper noted today it may be to much to ask that the compiler, during parsing, should be able to deduce that given std::tuple for Reduce map_reduce_best will yield a type.
On the other hand, compare this situation:
template<typename T> class S {
std::vector<std::conditional_t<sizeof(T) == 4, T, T*>> vec;
}:
What's the difference here, actually? We could build arbitrarily complex metafunctions instead of just std::vector<std::conditional<sizeof(T) == 4, T, T*>>
and the compiler would still have to figure out that the result is a type as long as there are no dependent names involved.
I don't see why the compiler would not evaluate map_reduce_best at parse time as there are no dependent names involved it will end up with a type as the result, thus not requiring any disambiguation. It is like the corollary of deferred kind checking: If you can kind check you can also kind check the result of the metafunction even if it has UAs or UTPs inside as their actual kind will be known. Yes, this does need some extra compiler logic, but I think it is fairly easy to implement.
It requires partial const-propagation, in effect.
I'm afraid the compiler will need dependent-dependent names while parsing template bodies :)
On Wed, Sep 28, 2022 at 8:49 PM Bengt Gustafsson @.***> wrote:
Yes, as Gasper noted today it may be to much to ask that the compiler, during parsing, should be able to deduce that given std::tuple for Reduce map_reduce_best will yield a type.
On the other hand, compare this situation:
template
class S { std::vector<std::conditional_t<sizeof(T) == 4, T, T*>> vec; }: What's the difference here, actually? We could build arbitrarily complex metafunctions instead of just std::vector<std::conditional<sizeof(T) == 4, T, T*>> and the compiler would still have to figure out that the result is a type as long as there are no dependent names involved.
I don't see why the compiler would not evaluate map_reduce_best at parse time as there are no dependent names involved it will end up with a type as the result, thus not requiring any disambiguation. It is like the corollary of deferred kind checking: If you can kind check you can also kind check the result of the metafunction even if it has UAs or UTPs inside as their actual kind will be known. Yes, this does need some extra compiler logic, but I think it is fairly easy to implement.
— Reply to this email directly, view it on GitHub https://github.com/atomgalaxy/isocpp-universal-template-param/issues/37#issuecomment-1261394817, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAA5R5L4GROCWP5QSKEWLJLWASON5ANCNFSM6AAAAAAQO7FBBA . You are receiving this because you are subscribed to this thread.Message ID: <atomgalaxy/isocpp-universal-template-param/issues/37/1261394817@ github.com>
I think this decision was wrong. It was taken in a haste. My reasoning now revolves around the map_reduce_best metafunction. This is a universal alias template whose kind will be known except in the unlikely case that one of the template arguments is dependent. It seems overly zealous to require disambiguation of the result every time map_reduce_best is called with a Reduce metafunction yielding a type.
Take the reducer
std::tuple
. With this convenient tuple builder we can for instance create a tuple of references easily:Note the definition of map_reduce_best from R3:
Thanks to co-variant behavior of template template parameters std::add_reference_t substitutes for Map and std::tuple substitutes for Reduce. It seems logical that
S::vs
can be declared without disambiguating the result of map_reduce_best as typename as there are no dependent names in its template argument list.