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
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