删除 C++ 中向量的常量限定符

remove const qualifier of vector in c++

提问人:Albert G Lieu 提问时间:2/6/2022 最后编辑:Albert G Lieu 更新时间:11/28/2022 访问量:2213

问:

是否可以去除向量的恒定性?如果是这样,如何实现?由于某种原因,我无法访问 ,我还能删除以下代码片段中的常量吗?感觉这和.我想这只是显式与隐式强制转换的一个例子,它们都创建了原始数组''''arr'''的副本。是否可以在不创建副本的情况下就地删除常量?main ()arrauto arr0 = const_cast<vector<int> & > (arr);vector<int> arr0 = arr;

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;


vector<int> func(const vector<int>& arr){
//    vector<int> arr0 = arr;
    auto arr0 = const_cast<vector<int> & > (arr);
    sort(arr0.begin(), arr0.end());
    return arr0;
}

int main(){
    const vector<int> arr = {3,4,1,5,2};
    auto res = func(arr);
    for (auto n:res)
        cout<<n<<" ";
    return 0;

}
C++(英语:C++) 常播

评论

0赞 chris 2/6/2022
你可以强制语言的手,但你不能修改常量数据。
0赞 Albert G Lieu 2/6/2022
@RetiredNinja鉴于我只能将代码添加到正文中,我还能删除常量吗?是的,我知道我们可以将 arr 传递给funcfun
0赞 Retired Ninja 2/6/2022
由于您编辑了代码以通过 const 引用而不是值传递,因此您应该在函数中进行复制。
0赞 Martin York 2/6/2022
更改函数参数的声明。void func(vector<int>& arr)
0赞 Sebastian 2/6/2022
您是否会问,是否有可能进行异位排序,即从常量向量读取并在新内存中写入,比向量的副本然后就地排序更有效?

答:

3赞 eerorika 2/6/2022 #1

不要试图抛弃恒心。修改 const 对象将导致未定义的行为。

感觉这和auto arr0 = const_cast<vector<int> & > (arr);vector<int> arr0 = arr;

它实际上是一样的。演员阵容是多余的。

是否可以在不创建副本的情况下就地删除常量?

如果您希望在不复制的情况下对向量进行排序,那么首先不要让向量成为常量。如果它是 const,则无法修改它。

那么在 C++ 中const_cast有什么意义呢?

它很少需要,但有一些用例。

您可以使用它将非常量 glvalue 表达式转换为常量表达式:

void fun(T&);       // overload 1
void fun(const T&); // overload 2
T t;
fun(t);                       // calls 1
fun(const_cast<const T&>(t)); // calls 2

如果你有一个可证明的非常量对象,并且有一个引用非常量对象的常量引用,那么你可以抛弃引用的常量性:

T t;
const T& ref = t;
const_cast<T&>(ref) = new_value;

同样的情况也适用于易失性限定符,尽管这种情况很少需要。

评论

0赞 doug 11/28/2022
只要你不修改 obj,抛弃 const 就不是 UB。请注意,vector 的内容不是 const,可以通过抛弃 const 来修改。你不能做的是通过修改obj,例如,push_back()
2赞 viraltaco_ 2/6/2022 #2

你可以做一个副本,它实现了你已经在尝试做的事情。 (你也可以得到回报值优化)。

#include <vector>
#include <algorithm>

template <class T>
static std::vector<T> func(std::vector<T> v) {
  std::sort(v.begin(), v.end());
  return v;
}

活生生
的例子 你永远不应该尝试修改一个变量,这是未定义的行为,它不需要做任何事情,无论它做什么都取决于编译器。
const

评论

0赞 Albert G Lieu 2/7/2022
You should never attempt to modify a const variable,我会相信你的话,但是如果 const 变量永远不应该改变,那么 have 在 c++ 中有什么意义呢?const_cast
0赞 eerorika 2/7/2022
@AlbertGLieu 查看我编辑过的答案。then what is the point of have const_cast in c++?
0赞 doug 11/28/2022 #3

你的例子很好。而且没有必要复印。没有未定义的行为。原因如下。这会将 arr 声明为顶级常量。如果没有 UB,则不能修改对象。但是,const 对象不包括动态内存内容。事实上,这些内容甚至不允许被声明为常量。

const vector<int> arr = {3,4,1,5,2};

你可以抛弃 constness,只要你不改变/写入 const 对象。调用 和 不会更改对象,因此不是未定义的行为。我在这里探讨了这一点arrv.begin()v.end()arr

这不是 UB,而是按内联方式排序。

void func(const vector<int>& arr){
    auto& arr0 = const_cast<vector<int> & > (arr);
    sort(arr0.begin(), arr0.end());
}

下面是 constexpr 函数中的代码示例:

#include <vector>
#include <algorithm>

consteval int foo()
{
    const std::vector<int> a = { 1,2,3 };
    auto& v = const_cast<std::vector<int>&>(a);
    v[0] = 42;
    std::sort(v.begin(), v.end());
    return a[2];
}

int main()
{
    return foo();  // returns 42 since sorted
}

编译器资源管理器