模板参数中引用类型的相等性
Equality of reference types in template parameters
C++ 标准在 [temp.type]#2.7 中说
Two values are template-argument-equivalent if they are of the same type and
...
(2.7) they are of reference type and they refer to the same object or function
这与在非模板代码中比较引用类型的方式不同。比如说
template <auto& x1, auto& x2>
constexpr bool equal_tmpl = false;
template <auto& x>
constexpr bool equal_tmpl<x, x> = true;
和
consteval bool equal_fun(auto& x1, auto& x2)
{
return x1 == x2;
}
意思不同。 equal_tmpl
比较地址,但 equal_fun
比较值:
constexpr int i = 123;
constexpr int j = 123;
static_assert(equal_tmpl<i, j> != equal_fun(i, j));
为什么在标准中这样定义?难道模板中的相等性与非模板代码中的相等性不一样吗? Demo.
出于模板参数等价的目的,我们想问的问题是“这两个参数相同吗?”而不是“这两个参数 相等 吗?”
对具有相同值的两个不同变量的引用可能彼此相等,但它们并不完全相同:一个不能替代另一个。想象一下,如果我们有这个:
template <const int& r>
constexpr auto foo() { return &r; }
如果标准说 foo<i>
和 foo<j>
是相同的函数,因为 i == j
(其中 i
和 j
是定义为问题)?不是,foo<i>
是returns地址i
的函数,foo<j>
是returns地址j
的函数,这两个地址不一样。
C++ 标准在 [temp.type]#2.7 中说
Two values are template-argument-equivalent if they are of the same type and
...
(2.7) they are of reference type and they refer to the same object or function
这与在非模板代码中比较引用类型的方式不同。比如说
template <auto& x1, auto& x2>
constexpr bool equal_tmpl = false;
template <auto& x>
constexpr bool equal_tmpl<x, x> = true;
和
consteval bool equal_fun(auto& x1, auto& x2)
{
return x1 == x2;
}
意思不同。 equal_tmpl
比较地址,但 equal_fun
比较值:
constexpr int i = 123;
constexpr int j = 123;
static_assert(equal_tmpl<i, j> != equal_fun(i, j));
为什么在标准中这样定义?难道模板中的相等性与非模板代码中的相等性不一样吗? Demo.
出于模板参数等价的目的,我们想问的问题是“这两个参数相同吗?”而不是“这两个参数 相等 吗?”
对具有相同值的两个不同变量的引用可能彼此相等,但它们并不完全相同:一个不能替代另一个。想象一下,如果我们有这个:
template <const int& r>
constexpr auto foo() { return &r; }
如果标准说 foo<i>
和 foo<j>
是相同的函数,因为 i == j
(其中 i
和 j
是定义为问题)?不是,foo<i>
是returns地址i
的函数,foo<j>
是returns地址j
的函数,这两个地址不一样。