提问人:Antonio 提问时间:9/29/2023 更新时间:9/29/2023 访问量:85
基本模板问题:“const const int*”在“const int”中的衰减
Basic template question: `const const int*` decay in `const int`
问:
以下代码
template <typename T>
struct A
{ static void f() {std::cout << "A<T>\n";} };
template <typename T>
struct A<const T>
{ static void f() {std::cout << "A<const T>\n";} };
template <typename T>
struct A<const T*>
{ static void f() {std::cout << "A<const T*>\n";} };
template <typename T>
void f()
{
A<const T>::f();
}
int main()
{
f<const int*>();
}
没有像我预期的那样工作。
我(错误地)认为调用函数的调用在这种情况下是,并且折叠成 .但这不是程序所做的,因为它打印意味着(在重新 )崩溃为 .f<const int*>()
A<const T>::f()
A<const const int*>:f()
const const int*
const int*
A<const T>
const const int*
const (const int*)
const int
但为什么会坍塌成?const const int*
const int
答:
你的假设是错误的。 不会“坍缩”成.const const int*
const int
调用 时,使用 进行实例化。这里,是 ,所以在哪里。f<const int*>()
f
T = const int* = int const*
int
const
T = U*
U = const int = int const
在 中,你调用 ,所以你用一个类型进行实例化。此处,指针是 。完整的类型是 或 。从来没有.f
A<const T>::f()
A
T2 = const T = U* const
const
const int * const
int const * const
const const int*
因此,选择了专业化,其中 .该版本不太专业,因为它是指向 的指针,而不是指针。添加另一个专业化可以更清楚地说明:const T
T = int const*
const T*
const T
const
template <typename T>
struct A<const T* const>
{ static void f() {std::cout << "A<const T* const>\n";} };
如果您反转展示位置,则更容易理解这种情况。也就是说,对于任何类型,都等价于 。事实上,这是“正常”的使用方式。通常适用于其左侧的类型。特殊情况是,if 是类型中的第一个单词,它直接应用于其右侧的类型,但这种特殊情况可能会使模板有点混乱。const
T
const T
T const
const
const
const
所以等价于 。请注意,它是 that's ,而不是指针:表示“指向常量的非常量指针”。f<const int*>()
f<int const*>()
int
const
int const*
int
在 中,由于等价于 和 是 ,变为:“指向常量的常量指针”。f<int const*>()
const T
T const
T
int const*
T const
int const* const
int
没有可以匹配的类型,因此部分专业化是不可行的。T
T const*
int const* const
A
评论
const T
是 (或 )。int const* const
const int* const
const const int *
T
int
"A<const T>"