基本模板问题:“const const int*”在“const int”中衰减

Ant*_*nio 0 c++ templates metaprogramming

下面的代码

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*>();
}

Run Code Online (Sandbox Code Playgroud)

没有像我预期的那样工作。

我(错误地)认为对 call 的调用在本例中是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

Nel*_*eal 5

你的假设是错误的。const const int*不会“塌陷”成const int.

当您调用时f<const int*>(),您会实例fT = const int* = int const*. 这里,intconst,所以T = U*哪里U = const int = int const

在 中f,您调用A<const T>::f(),因此您A使用类型进行实例化T2 = const T = U* const。这里,指针是const。完整的类型是const int * constor 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";} };
Run Code Online (Sandbox Code Playgroud)

演示