【问题标题】:Not understanding C++ type mismatch: const Foo* to Foo* const&不理解 C++ 类型不匹配:const Foo* to Foo* const&
【发布时间】:2015-05-05 02:02:27
【问题描述】:

拥有这组对象和语句:

QSet<Foo*> set;
iterator QSet::insert(const T & value)    //type of the function I want to call
const Foo * get() const                   //type of the function I use to get the argument

set.insert(get());                        //the line showing up as error

我收到错误“没有已知的参数 1 从 'const Foo*' 到 'Foo* const& 的转换”。我想我在阅读这些类型时遇到了麻烦,因为我不知道该怎么做才能完成这项工作。

根据我的阅读, const 关键字适用于其左侧的类型,但顶级 const 除外,它可以写入它所适用的类型的左侧。我的猜测是我必须将 get() 转换为引用,但我不确定该怎么做。

【问题讨论】:

  • 这不是“顶级const”。 get() 返回指向“const Foo”的指针,而不是 const 指针。
  • 所以我的理解是 const 在开头适用于它正确的一切是错误的?那么这样的const到底适用于什么?

标签: c++ pointers reference constants


【解决方案1】:

这里似乎存在一些误解(提问者和一些答案)。

首先,您说“我的猜测是我必须将 get() 转换为参考,但我不确定如何做到这一点”。让我们尝试解决这个问题:

1) “我必须将get() 转换为参考”——实际上,你不需要!

iterator QSet::insert(const T &amp; value) 确实有参考。但它是对类型T 的引用。所以问题是,“T 类型是什么?

在这种情况下,T=Foo *。所以insert,在这个模板实例中,实际上是:

iterator QSet::insert(Foo * const &amp; value) -- 从右到左读取:insert 引用指向 Foo 的常量指针。

2) “我不确定如何做到这一点 [将指针转换为引用]”——虽然您不必在这里执行此操作,但通常您可以通过取消引用 get 的结果来执行此操作。例如:*(get())

第二,编译器错误。出现错误是因为存在冲突:

a) get() 返回 const Foo *

b) 但set 存储Foo*——不是const Foo *,所以insert 只接受可更改的Foo

因此您不能在QSet&lt;Foo*&gt; 中存储常量指针。这是有道理的,因为您可以使用set 访问和更改其中的Foos,而您承诺不会使用const Foo

这个参考应该会有所帮助:

https://isocpp.org/wiki/faq/const-correctness

您可能还想是否可以只使用QSet&lt;Foo&gt; 而不是QSet&lt;Foo*&gt;。在前一种情况下,事情可能会按照您的预期进行。

【讨论】:

  • isocpp.org/wiki/faq/const-correctness#const-ref-alt,对于任意复杂的类型构造Xconst X* 是否等同于X const*
  • X 是一个类型时——不是X 更复杂。事实上,这就是为什么我必须在替换T 之前进行完全交换。写X const* 可以更容易地从右到左阅读(“指向常量X 的指针)。但是写const X* 可以在源代码中更明显地表明类型是“常量X "。所以通常你会在代码中看到它const X*
  • 对于模板,它可能会令人困惑,所以......写QSet 的人可能已经编码了insert(const T &amp; value) insert(T const &amp; value),它们本来是一样的。但那是因为编译器知道该做什么。如果想在纸上或脑海中替换T,您必须在进行替换之前将其视为insert(T const &amp; value)
  • 所以const (int *) * pcp 是一个指向int 的const 指针?或者这是一个无效的案例?
  • 我认为你不能这样使用括号。 g++ 给了我一个编译器错误。如果没有括号,const int ** pcp 将是一个可变指针,指向一个指向常量int 的可变指针,而int * const * pcp 将是一个可变指针,指向一个指向可变int 的常量指针。
【解决方案2】:

您正在尝试获取const Foo * 并将其插入QSet&lt;Foo *&gt;,但编译器不会自动将const Foo * 转换为普通的Foo *

【讨论】:

  • @Jefffrey:因为QSet&lt;Foo *&gt; 包含非常量指针。您不能将指向 const 的指针隐式更改为指向非常量的指针。
【解决方案3】:

我通过如下改变集合的类型解决了这个问题。

QSet<Foo const*> set;

通过此更改,编译成功。

【讨论】:

    【解决方案4】:

    您违反了从 get() 函数返回的指针的常量性。 get() 返回一个指向 Foo 类型的 const 对象的指针,但随后您尝试将其插入非 const Foo 指针的向量中。您需要将 const_cast 的返回值从 get() 更改为 get() 的返回类型从 const Foo* 更改为 Foo*

    【讨论】:

    • 这将是另外两个选择。
    猜你喜欢
    • 2011-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-12
    • 1970-01-01
    • 1970-01-01
    • 2015-01-13
    • 2012-06-12
    相关资源
    最近更新 更多