带const且不带const限定符的类型定义

typedef with const and without const qualifier

本文关键字:const 定义 类型      更新时间:2023-10-16
    typedef void* TVPtr;
    typedef const void* CTVPtr;
const TVPtr func3 (const TVPtr p)
{
    return p;
}
const void* func4 (const void* p)
{
    return p;
}
CTVPtr func5 (CTVPtr p)
{
    return p;
}

int main ()
{
    const uint64_t i = 10;
    func3(&i);  // compilation error here
                // cannot convert argument 1 from 'const uint64_t *' 
                // to 'const TVPtr' Conversion loses qualifiers    
    func4(&i);  // no compilation error
    func5(&i);  // no compilation error
    return 0;
}

我不明白为什么有错误是一种情况,而不是在其他两个?

const TVPtr不是const void*,而是void* const。换句话说,它不是指向const void的指针,而是指向voidconst指针。由于i被声明为const,它将很高兴绑定到const void*,而不是void* const,因为这将丢弃对象本身的const属性。

const TVPtr

的意思是:

void * const  //correct

:

const void*   //wrong

你似乎认为。


可视化有力量影响你的理解。

这就是为什么我认为把const放在类型后面是一个更好的做法的一个原因。所以如果你有这样的做法:

void const * x;
不是

const void * x; //same as void const *x!

那么它可以帮助定义类型和模板。

例如,取typepedef:

typedef void* voidptr;

现在,如果你写下面的代码,并试着想象它是什么:

voidptr const x;

那么你更有可能把它想象成:

void* const x; //correct

,这是事实。

在类型前加上const是违反直觉的:

const voidptr x;

似乎是:

const void* x; //wrong

实际上是错误的-它仍然是:

 void* const x; //correct

因此,将const放在类型之后有助于可视化最终类型

func3期望非const类型,并承诺不通过实参列表中类型前面的const关键字更改它。因为CTVPtr是指向const数据的指针,所以其他函数可以接受指向const类型的指针。

我认为混淆来自于你使用的const关键字,这实际上意味着func3不会改变p所指向的数据,而不是说func3将接受一个const TVPtr。

如果你真的想把i的地址传递给func3,你可以像这样强制转换它

func3( (void*)&i);
相关文章: