Date: Fri, 19 Nov 2021 10:16:04 -0500
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_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
Received on 2021-11-19 09:16:18