加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 编译器忽略函数参数的’const’

发布时间:2020-12-16 10:05:33 所属栏目:百科 来源:网络整理
导读:我有编译错误的问题,看看这段代码: templateclass Tstruct MyStruct{};templatestruct MyStructint{ typedef int* type;};templateclass Tvoid foo(const typename MyStructT::type myType){}int main(){ const int* ptr = NULL; fooint(ptr); return 0;}
我有编译错误的问题,看看这段代码:

template<class T>
struct MyStruct
{
};

template<>
struct MyStruct<int>
{
    typedef int* type;
};

template<class T>
void foo(const typename MyStruct<T>::type myType)
{
}

int main()
{
    const int* ptr = NULL;
    foo<int>(ptr);

    return 0;
}

问题是编译器忽略了foo函数上的’const’,使得对foo的调用非法(const int * to int *).

Severity Code Description Project File Line Suppression State
Error C2664 ‘void foo(const MyStruct::type)’: cannot convert argument 1 from ‘const int *’ to ‘const MyStruct::type’

我在Visual Studio和gcc的5.3编译器中测试了以下代码,它们都丢失了同样的错误.

编译器是故意这样做的吗?为什么会这样?

解决方法

const int *和int * const之间有一个重要的区别.有关差异的解释,请参见 this answer.

考虑一下const typename MyStruct< T> :: type的含义.它是一个MyStruct< T> ::类型的const.在这种情况下,它是一个int *即const.这是一个int * const,一个不能重新分配新地址的指针,但仍可用于修改指向的int.但是,您在foo< int>(ptr)中传递的指针是一个const int *,它不能转换为int * const,因为它将丢弃const限定符.

为了达到你想要的效果,const必须成为类型的一部分才能成为指针.它不能在事后添加,或者它总是被解释为T * const.您可以使用类型特征来删除类型的指针部分,添加const然后使其成为指针.

#include <type_traits>

template<class T>
struct MyStruct { };

template<>
struct MyStruct<int> {
    typedef int* type;
};

template<class T>
void foo( std::add_const_t<std::remove_pointer_t<typename MyStruct<T>::type>> * myType) {}

int main()
{
    const int* ptr = nullptr;
    foo<int>(ptr);

    return 0;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读