C++ Logo

std-proposals

Advanced search

Re: Explicit alias template specialization

From: Nicolas Weidmann <n.weidmann_at_[hidden]>
Date: Fri, 19 Nov 2021 16:31:09 +0100
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>{});
}

Nicolas

Sent from my iPhone

> On 19 Nov 2021, at 16:16, Arthur O'Dwyer via Std-Proposals <std-proposals_at_[hidden]> wrote:
>
> 
>> On Fri, Nov 19, 2021 at 10:07 AM Nicolas Weidmann via Std-Proposals <std-proposals_at_[hidden]> wrote:
>
>> Thank you for your replies.
>> But the problem you are raising with your example already exists now:
>>
>> 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(alias3<T>) { }
>
> Here the signature of `bar` (looking through the "transparent" aliases) is
>
> template<typename T> void bar(no_default_alias3<T>::type) { }
>
> The template parameter `T` cannot be deduced, because it's "firewalled" behind a member typedef of a dependent type. This is the primary use-case for C++20 `std::identity` — as a type-deduction firewall:
>
> template<class T> void baz1(T a, T b);
> template<class T> void baz2(T a, typename std::identity<T>::type b);
> int main() {
> baz1(sizeof(int), 0); // deduction fails: `a` says T=size_t but `b` says T=int
> baz2(sizeof(int), 0); // deduction succeeds: `a` says T=size_t, and `b` does not contribute to deduction
> }
>
> We also define
> template<class T> identity_t = typename std::identity<T>::type;
> as an alias template so that we don't have to write out the whole long thing every time. This is "free" because the compiler will just look straight through aliases: `identity_t<T>` is exactly equivalent to `std::identity<T>::type` in every place it's written.
>
> HTH,
> Arthur
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2021-11-19 09:31:14