标签: const-correctness

将变量传递给具有常量参数的函数

我很困惑。我看到当代码是这样的

void fun(const char **p) { }
int main(int argc, char **argv)
{
   fun(argv);
   getchar();
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

它显示error: invalid conversion from 'char**' to 'const char**'

但是当代码像这样

void test(const char *p) { }
int main()
{
    char *c = new char('a');
    test(c);
}
Run Code Online (Sandbox Code Playgroud)

然后就没有编译错误了。两个代码有什么区别?
为什么第二段代码可以将变量传递给常参数的函数?

c++ pointers const-correctness

6
推荐指数
1
解决办法
152
查看次数

从"foo <T>"转换为"const foo <const T>" - C++

我有一个函数(请不要关心通过引用返回临时.这只是一个解释问题的例子),

const foo<const int>& get_const()
{
    foo<int> f;
    return f;
}
Run Code Online (Sandbox Code Playgroud)

这显然不会编译.我正在寻找一种方法,以确保调用方不会改变Tfoo.我该如何确保?

我见过类似的行为boost::shared_ptr.shared_ptr<T>可转换为const shared_ptr<const T>.我无法弄清楚它是如何做到这一点的.

任何帮助都会很棒.

c++ templates constants const-correctness

5
推荐指数
2
解决办法
1441
查看次数

在C++中使用const的正确方法是什么?

const正确让我有些困惑.

您使用什么经验法则来决定什么时候应该是const?

例如,考虑这个例子

class MyClass
{
  string ToString(); // this one?
  const string& ToString(); // or this? 
  const string& ToString() const; // or this?

  char* ToString(); // What about this?
  const char* ToString(); // or this?
  const char* ToString() const; // or this?
  const char const* ToString(); // Is this legal?
  const char const* ToString() const; // how about this?
  char const* ToString();  // or even this?
};
Run Code Online (Sandbox Code Playgroud)

Const可能会让人感到困惑.

所有这些ToString方法之间有什么区别?

如果我理解正确,第一个返回一个新的字符串对象,如果需要可以修改.第二个返回一个常量引用,也许它应该是字符串const和ToString().第三个可能是废话,因为引用总是不变的是正确的吗?

以为我会把旧的char*版本放在那里进行比较,因为我有返回对象指针的方法,我不确定它们是否应该是const.

我想我只是想了解const正确性的局限性和好处,以及如何预先确定某些东西是否应该是const以及如何正确地应用const,因为将const放在不同的位置会改变含义.

编辑:另外,我如何处理'...丢弃限定符'.这究竟意味着什么?

c++ const const-correctness

5
推荐指数
1
解决办法
720
查看次数

懒惰的评估和const正确性的问题

我制作了一个openGL相机类,它使用延迟评估通过getter函数提供最终投影或模型 - 视图 - 投影矩阵.用户在实例的整个生命周期(FOV,位置等)中提供各种相机参数,但不是每次更改参数时都重新计算投影矩阵和/或MVP矩阵,而是设置"已更改"标志(即旧的缓存矩阵现在无效).只要用户随后请求更新的最终矩阵,就会重新计算,结果缓存,并返回const引用.

一切都听起来不错,直到我打电话给我:

const QMatrix4x4& oE_GLCamera::getModelViewProjection() const;
Run Code Online (Sandbox Code Playgroud)

来自const oE_GLCamera实例的函数...我在我的应用程序中使用const引用来从CAD视口中提取相机数据而不更改相机,但是如果它们无效,我的getter函数会对成员变量执行惰性求值 - 因此会破坏const正确性.

是否有语言功能或设计范例我不知道如何帮助解决这个问题?或者懒惰的评估从根本上与const正确性不兼容?我知道const_cast <>,我自己从未使用过它,但读了一些关于它的内容,可以归结为:如果你使用它,你已经在某个地方出错了.还是会成为我的救世主?

Cam,任何建议都会得到很好的接受

c++ const-correctness lazy-evaluation

5
推荐指数
1
解决办法
634
查看次数

const正确性和shared_ptr,设计问题?

我最近开始尝试在我的代码中强制执行const正确性.在函数定义中,我提供一个指向类的常量对象的常量指针LorentzM:

void AnalysisObject::SetOwnedPointer(const int maptotree_In, const LorentzM* const momentum_In){ 
owned_pp4_original.reset(momentum_In); 
maptotree=maptotree_In;
}
Run Code Online (Sandbox Code Playgroud)

这里owned_pp4_original

shared_ptr<LorentzM> owned_pp4_original;
Run Code Online (Sandbox Code Playgroud)

我这样做,因为这个函数,SetOwnedPointer,永远LorentzM* momentum_In不应该更改它也不应该更改它指向的对象,因此它是常量指针.

然而,一个shared_ptr创建到momentum_In指向的对象,我想用这个shared_ptr的改变对象以后:

void ChangeLorentzM(const double px, const double py, const double pz, const double E){
owned_pp4_original->SetPxPyPzE(px,py,pz,E); //THIS CHANGES THE OBJECT
}
Run Code Online (Sandbox Code Playgroud)

所以,一方面,能够做到:

owned_pp4_original.reset(momentum_In); 
Run Code Online (Sandbox Code Playgroud)

owned_pp4_original 应该是一个 shared_ptr<const LorentzM>

但是,我无法通过它改变对象.

这张照片有什么问题?

非常感谢.

c++ boost const-correctness shared-ptr

5
推荐指数
1
解决办法
267
查看次数

何时以及如何在D中使用`const`和`immutable`?

在许多现代语言中,const应该使用正确性来阐明接口和意图,并为编译器提供一些优化的机会.在D中,存在真正不可变数据的很酷的特征.应该如何constimmutable使用?我有点想,更喜欢const作为函数参数和immutable局部变量的限定符似乎是编写代码的好方法,但是只要你想要一个带有引用或指针的结构,如数据成员(私有或非私有),不可变的变量,你不能这样做.

struct S {
    private int[] data;
}

void main() {
    immutable s = new S; // won't work, since members aren't immutable
}
Run Code Online (Sandbox Code Playgroud)

因此,struct如果我使用不可变的话,更改a的实现会破坏我的代码.我是否更喜欢const局部变量并仅在必要时使用不可变?指导方针是什么?

d const-correctness immutability

5
推荐指数
1
解决办法
316
查看次数

使用字符串文字初始化非const参数

所以我有这个代码:

class ConstTest {
public:
    explicit ConstTest(char* name) {}
};

int main() {
    ConstTest t("blarghgh");
}
Run Code Online (Sandbox Code Playgroud)

它显然是编译,即使我认为它不应该.由于C++中的字符串文字具有类型const char[],而ConstTest构造函数需要const-less char*- not const char*.并且const通过C++隐式地执行指向非常量指针的指针.

那么,我哪里错了?为什么要编译?我可以合法地修改构造函数中的解除引用指针吗?!

c++ const-correctness

5
推荐指数
1
解决办法
838
查看次数

阻止const类函数在引用成员上调用非const类函数

请原谅我这个相当模糊的标题,但它确实有点说出来.这就是我的意思

class A
{
    void DoSomething(); // non-const
}
Class B
{
public:
    B(A& a) : _a(a) { }
    // const function
    void DoSomethingElse() const
    {
        // Is there a way to disallow this?
        _a.DoSomething();
    }
    void DoEvenMore()
    {
        // Should be OK
        _a.DoSomething();
    }
private:
    // Can't make it const A& because it needs
    // be non-const for non-const functions
    A& _a; // A reference
}
Run Code Online (Sandbox Code Playgroud)

那么有什么方法可以防止B::DoSomethingElse()打电话A::DoSomething()
但是,B::DoEventMore()哪个不const应该继续通话.

我正在使用Visual C++ 2013. …

c++ const-correctness visual-c++ c++11

5
推荐指数
2
解决办法
227
查看次数

const容器的正确性

经过多年盲目地接受std::vector<T>::operator[] const返回的事实const_reference,但是,鉴于const如何为智能指针工作,我现在开始想知道为什么它和其他STL容器都是这样设计的.似乎a的"constness" const std::vector既适用于向量及其元素,而对于智能指针,"constness"仅适用于指针而不适用于它所指向的元素.

为了澄清,似乎应该有一个类似矢量的容器,const这意味着用户不能改变容器的大小,但容器中的元素是可变的.我的主要问题是:是否有某些东西可以阻止这种类型的容器"const正确"?

似乎通过添加一个额外的间接层(例如std::vector<std::unique_ptr<T>> const)来实现这一点有一些hackish变通方法,但我正在寻找一些在维护方面不那么尴尬的东西.

顺便说一句,如果在STL容器之前将智能指针合并到语言中,那么const访问器是否仍然按照它们今天的方式定义?

c++ stl const-correctness

5
推荐指数
1
解决办法
199
查看次数

我可以将const char*数组传递给execv吗?

这是原型execv:

int execv(const char *path, char *const argv[]);
Run Code Online (Sandbox Code Playgroud)

我可以传递一个const char指针数组作为第二个参数吗?

此示例程序在USE_CAST未设置时发出警告:

#include <unistd.h>
int main(int argc, char *argv[])
{
    if (argc > 0) {
        const char *exe_name = "/bin/echo", *message = "You ran";
        const char *exe_args[] = { exe_name, message, argv[0], NULL };
#ifdef USE_CAST
    execv("/bin/echo", (char **) exe_args);
#else
    execv("/bin/echo", exe_args);
#endif
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

在编译时,gcc说,"如果我不使用强制转换,则从不兼容的指针类型传递'execv'的参数2".

POSIX文档execv(中途理由部分),它看起来像第二个参数是char *const为了向后兼容数组:

包含有关argv[]envp[]成为常量的语句,以明确未来的语言绑定编写者,这些对象是完全不变的.......遗憾的是,第四列无法使用......

"第四栏"所指的地方const char* …

c posix const const-correctness exec

5
推荐指数
1
解决办法
2034
查看次数