【问题标题】:Pushing constant pointers to std::stack<T *> gives a compile error将常量指针推送到 std::stack<T *> 会产生编译错误
【发布时间】:2019-07-05 10:01:51
【问题描述】:

以下代码导致以下编译错误:

error: no matching member function for call to 'push' 
st.push(ptr);

如果我删除funcptr 参数的const,问题就会消失。所以这似乎意味着你不能将常量指针压入堆栈。为什么会这样?如果我尝试将其推入std::queue,它似乎也会给出相同的错误,并且我也怀疑其他容器。

#include <iostream>
#include <stack>

void func(const int *&ptr)
{
   std::stack<int *> st;
   st.push(ptr);
}

int main(int argc, char const *argv[])
{    
   int i = 2;
   auto ptr = &i;
   func(ptr);
}

【问题讨论】:

  • A const T * 不能被隐式转换(并且几乎不应该被显式转换)为T *。您正在尝试将 const int * 存储到需要转换的 int * 容器中。
  • 它不是“常量指针”,而是指向 const int 的指针
  • 决定你的栈是否包含常量对象。如果是这样,那么您只需将指针传递给常量对象就没有困难了。不是,那就不要尝试将指向 const 对象的指针放入其中。

标签: c++ pointers stack constants push


【解决方案1】:

const 指针的目的是确保指向的对象不能被修改(至少不能通过这个指针)。

如果在将指针压入堆栈时可以将const int* 转换为int*,则可以通过弹出非 const 指针来更改对象。这就是此代码无法编译的原因。

解决办法是让栈变成一堆const指针

void func(const int *&ptr)
{
   std::stack<const int *> st;
   st.push(ptr);
}

现在这还不够:您的问题随后会将错误消息转移给调用者。你可以解决这个问题:

int main(int argc, char const *argv[])
{    
   int i = 2;
   const int* ptr = &i;   // <------ not auto
   func(ptr);
}

为什么?因为该函数需要对 const 指针的引用作为参数。传递普通指针 ptr 不允许构建对 const 指针的引用。

如果您通过值而不是引用传递指针,则无论ptr 是否为 const 都可以,因为允许编译器将非 const 指针值隐式转换为 const 值。

【讨论】:

    【解决方案2】:

    使堆栈包含const int *:

    void func(const int *&ptr)
    {
       std::stack<const int *> st;  // <== Add const before int * here.
       st.push(ptr);
    }
    

    解释:

    一个 const 指针意味着:你可以读取它指向的东西,但你不能写入它指向的东西。并且非常量指针(即普通指针)可以读取和写入它指向的东西。编译器始终检查您是否只在分配指针时收紧功能。

    您可以将非常量指针压入包含 const 指针的堆栈。堆栈中的指针将始终是 const 指针,并且能够比原来的指针做 less

    另一方面,您可能不会将 const 指针推入非 const 指针堆栈(这是您的情况),因为这样您就可以使用堆栈中的指针做比以前允许的更多的事情。

    换句话说:你可以一直添加 const,但你可能永远不会 (*) 再次删除它。

    (*) 您可以通过强制转换来删除const,但只有在您确切知道自己在做什么的情况下才应该这样做。这通常是不必要的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-10-23
      • 2021-12-13
      • 2013-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-10-12
      • 2020-03-10
      相关资源
      最近更新 更多