C++ Logo

std-proposals

Advanced search

Re: Explicit alias template specialization

From: Nicolas Weidmann <n.weidmann_at_[hidden]>
Date: Fri, 19 Nov 2021 17:54:56 +0100
If I correctly understood Arthur,

My proposal is like introducing dependent types in a non transparent manner.

Regarding your example you already have the type deduction issue with std::type_identity_t:

template<typename T> void foo(std::type_identity_t<T>);

Nicolas

Sent from my iPhone

> On 19 Nov 2021, at 17:28, Martin Vejnár via Std-Proposals <std-proposals_at_[hidden]> wrote:
>
> 
> Nicolas, consider
>
> template <typename T>
> using vec = std::vector<T>;
>
> template <typename T>
> void foo(vec<T> v);
>
> When you pass `std::vector<int>{}` to `foo`, `T` gets deduced to `int`. This works, because `vec<T>` is equivalent to `std::vector<T>` and we can deduce `T` in `std::vector<T>` from `std::vector<int>`.
>
> With your proposal, however, `vec<T>` is no longer necessarily equivalent to `std::vector<T>`. It is also not obvious how template argument deduction should be modified to ensure that `T` still gets deduced to `int` in my example. What do you propose?
>
>> On Fri, Nov 19, 2021 at 4:59 PM Nicolas Weidmann via Std-Proposals <std-proposals_at_[hidden]> wrote:
>> All I am saying is that alias templates are not as transparent to type deduction as written in your first response.
>>
>> Then why allow the usage of dependent types in alias templates and allow something like std::type_identity_t?
>>
>> Nicolas
>>
>>
>>
>> Sent from my iPhone
>>
>>>> On 19 Nov 2021, at 16:43, Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]> wrote:
>>>>
>>> 
>>>> On Fri, Nov 19, 2021 at 10:31 AM Nicolas Weidmann <n.weidmann_at_[hidden]> wrote:
>>>
>>>> Based on your last example, we would get:
>>>>
>>>> #include <vector>
>>>> #include <set>
>>>> #include <string>
>>>>
>>>> template<typename> struct no_default_alias3;
>>>>
>>>> template<> struct no_default_alias3<int> {
>>>> using type = std::vector<int>;
>>>> };
>>>>
>>>> template<typename T> using alias3 = typename no_default_alias3<T>::type;
>>>>
>>>> template<typename T> void bar(T a, alias3<T>) { }
>>>>
>>>> template<> struct no_default_alias3<float> {
>>>> using type = std::vector<int>;
>>>> };
>>>>
>>>> template<> struct no_default_alias3<bool> {
>>>> using type = std::set<std::string>;
>>>> };
>>>>
>>>> void foo()
>>>> {
>>>> bar(1.0f, std::vector<int>{});
>>>> bar(true, std::set<std::string>{});
>>>> }
>>>
>>> IIUC, you've just renamed `std::identity` to `no_default_alias3` and left everything else the same; is that right?
>>> So your `no_default_alias3` template is serving as a "type deduction firewall," in the same way as `std::identity` does today.
>>> And in particular, it is not acting in the same way as an alias template does today (because aliases do not serve as firewalls).
>>>
>>> I think we're now going around in circles, but just in case, let me show you a program that directly compares the (transparent) behavior of aliases with the (firewalling) behavior of non-aliases.
>>>
>>> template<class T> using Alias = T;
>>> template<class T> struct Nonalias { using type = T; };
>>>
>>> template<class T> void take_alias(Alias<T>); // OK, equivalent to void take_alias(T); T is deducible
>>> template<class T> void take_nonalias(typename Nonalias<T>::type); // OK, but T is not deducible
>>>
>>> int main() {
>>> take_alias(42); // OK, T=int
>>> take_nonalias(42); // does not compile, T can't be deduced
>>> }
>>>
>>> My impression of your original message/proposal is that you don't understand this fundamental difference between aliases and nonaliases, and you're basically proposing that either (1) some-or-all kinds of aliases should behave more like nonaliases, or (2) it should be possible to define (certain kinds of) nonaliases using a slight variation of alias syntax (instead of using the existing nonalias syntax).
>>>
>>> HTH,
>>> Arthur
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2021-11-19 10:55:05