C++ Logo

std-discussion

Advanced search

auto& NTTP and type equivalence

From: Lénárd Szolnoki <cpp_at_[hidden]>
Date: Tue, 8 Dec 2020 19:30:33 +0000
Greetings,

Consider the following code:

```
#include <type_traits>

template <auto& x>
struct S {
    using type = decltype(x);
};

int i;
constexpr const int& cref = i;

static_assert(std::is_same_v<
    S<i>::type, decltype((i))
>, "A");

static_assert(std::is_same_v<
    S<cref>::type, decltype((cref))
>, "B");

static_assert(std::is_same_v<
    S<i>, S<cref>
>, "C");
```

In both C++17 and C++20 in S<i> the deduced parameter type is
`int &` and in S<cref> the deduced parameter type is `const int&`,
therefore the first too assertions should pass.

In C++17 S<i> and S<cref> refer to the same class, because the
corresponding NTTP of reference type refer to the same object.

https://timsong-cpp.github.io/cppwp/n4659/temp.type#1.6

But if S<i> and S<cref> refer to the same class, then S<i>::type and
S<cref>::type must be the same, but that contradicts with the first too
assertions.

This seems to be a defect in C++17, but I didn't find a corresponding
issue or defect report.

In C++20 S<i> and S<cref> are separate types, because i and cref are
not "tempplate-argument-equivalent", as it requires the type of i and
cref to be the same:

http://eel.is/c++draft/temp.type#2

The change of wording in this area was introduced by
http://wg21.link/P1927 , but I don't know if the resolution of the
C++17 issue described above was intentional or not.

One issue with this resolution is that the mangled name of S<i> and
S<cref> are the same in the Itanium ABI. Related gcc ticket:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98163

In summary:

1. There is an issue in C++17, that seems to be resolved in C++20, but
there doesn't seem to be a defect report that is applied to previous
standards.
2. The resolution conflicts with the Itanium ABI's name mangling.

Regards,
Lénárd

Received on 2020-12-08 13:30:41