标签: const-reference

如果没有const引用,是否会删除临时对象?

让我们来看看这两个功能:

std::string get_string()
{
    std::string ret_value;
    // Calculate ret_value ...
    return ret_value;
}

void process_c_string(const char* s)
{
    std::cout << s << endl;
}
Run Code Online (Sandbox Code Playgroud)

这里有两个可能的process_c_string带有参数的调用get_string.

  1. 没有绑定const引用的返回对象get_string.

    process_c_string(get_string().c_str());
    
    Run Code Online (Sandbox Code Playgroud)
  2. 用绑定const引用返回的对象get_string.

    const std::string& tmp_str = get_string();
    process_c_string(tmp_str.c_str());
    
    Run Code Online (Sandbox Code Playgroud)

我知道第二种方式是有效的,但第一种方式是什么,标准对此案例有什么看法呢?返回的临时对象是否get_string会在process_c_str完成之前删除,因为没有const reference它?

注意:这两个版本在MSVC中都可以.

c++ temporary const-reference reference-binding

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

为const引用成员分配temp会导致分段错误

通过一个例子更好地解释:

tok.h

#include <string>

static const char* defaultDelim = ".,;";

class Tokenizer {
public:
    Tokenizer():
        // 'delim' is the const ref member that is initialized by the temp string 
        delim( (altDelim.size())? altDelim : std::string(defaultDelim) ) 
    {}

    size_t scan(const std::string& str)
    { return str.find_first_of(delim); }

    static void setDelim(const std::string& d) { altDelim = d; }
private:
    static std::string altDelim;
    const std::string& delim;
};
Run Code Online (Sandbox Code Playgroud)

main.cpp中

#include <iostream>
using namespace std;

#include "tok.h"

std::string Tokenizer::altDelim;

int main()
{
    Tokenizer tok;

    size_t pos = …
Run Code Online (Sandbox Code Playgroud)

c++ constructor const-reference temporary-objects

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

通过大参数自动使用const-ref

当我有下面的伪类:

template <class T> class tmplClass
{
    void doSomething(T input);
};
Run Code Online (Sandbox Code Playgroud)

有一种方法来改变void doSomething(T input)void doSomething(const T& input)时的sizeof(T)是在较大的系统架构.

tmplClass<char> c;例如,void doSomething(T input)当您有tmplClass<[another big class with lots of variables]>使用时,意味着使用void doSomething(const T& input)

  1. 我能从中获得任何优化吗?
  2. 有什么我需要做的,或者gcc可以自动执行此操作
  3. 如果我必须做某事,那又怎样?

c++ templates const-reference

4
推荐指数
2
解决办法
102
查看次数

当const引用绑定到临时引用时,堆栈中会发生什么?

C++标准允许将const引用绑定到rvalues,从而延长临时的生命周期,直到引用超出范围.但是,我无法弄清楚这是如何实际编译的,让我用一个例子来解释:

std::string foo() {
    return std::string("foo");
}

void bar() {
    VeryBigObject obj;
    // Perhaps do something with the big object
}

int main(int, char **) {
    const std::string &foo_str = foo();
    bar();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

据我所知,使用x86架构作为例子,首先foo()调用函数并在堆栈中构造字符串对象,这意味着从rsp寄存器中减去所需的空间量(假设为64)位结构); 之后,rsp寄存器返回其原始值,释放函数foo()正在填充的堆栈空间,如果我理解正确,调用bar()将使用该堆栈空间来构造VeryBigObject,这将覆盖该字符串.

考虑到所有这些,在调用foo()汇编域后,如何延长字符串的生命周期?

c++ stack const-reference

4
推荐指数
1
解决办法
108
查看次数

为什么对字符串参数的const引用可以采用字符串文字?

为什么对字符串参数的const引用可以采用字符串文字?像字符串文字"hello"不是变量,为什么这段代码有效?

class CVector {
    public:
        int x, y;
        CVector() {};
        ~CVector() { delete ptr; }
        string* ptr;
        void doSomething(const string& str) { ptr = new string(str); }
        void print() { cout << "\n" << *ptr; }
};
int main()
{
    result.doSomething("asdas");
    result.print();
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

首先,我认为引用作为参数用于避免复制过程并直接访问作为参数的变量(尽管我仍然可以正确).但字符串文字"asdas"不是变量,为什么参数将字符串文字作为参数?我的意思是因为参数str是一个引用,它将成为该实体的别名,对吧?如果是这样,文字是否只是变量?

参数列表不应该由string& strconst引用而不是const引用组成,因此文本将用于构造str

并且只要引用是活着的,并不是const引用使引用的实体保持活动状态?如果是这样,你为什么要这样做呢?

c++ string reference string-literals const-reference

4
推荐指数
1
解决办法
1662
查看次数

从函数返回临时对象的引用

考虑以下代码 -

#include <iostream>
#include <stdio.h>

const int & retRef() {
    return 6;
}

int main()
{
    const int& k = retRef();
    printf("Value: %d\n", k);
    printf("Address: %p\n", &k);
    printf("Value: %d\n", k);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出是 -

Value: 6
Address: 0x7ffd45bf544c
Value: 32692
Run Code Online (Sandbox Code Playgroud)

为什么在打印变量的地址后值发生了变化k?如果我更换线const int& k = retRef()const int& k = 6;的输出为预期.

为什么这种行为不同?提前致谢

c++ lifetime const-reference temporary-objects

4
推荐指数
1
解决办法
127
查看次数

初始化列表中对象的生命周期可以延长吗?

我的印象是,它的std::initializer_list行为可能类似于 C++ 中的文字字符串,甚至进一步,它们可能会延长 const 引用的生命周期。这是正确的评估吗?

initializer_list稍后可以在本地范围内以某种方式引用an 中的对象(无需复制它们)吗?在全球范围内?

例如,这个测试在 GCC 和 clang 中通过。这只是偶然吗?

#include<cassert>
#include<initializer_list> 
struct A{
    double const* p;
    A(std::initializer_list<double> il){ p = &*(il.begin() + 1); };
};
double f(){return 5.;}
int main(){
   A a1{1.,2.,3.};
   assert( *a1.p == 2. );
   A a2{1., f(), f()};
   assert( *a2.p == 5. );
}
Run Code Online (Sandbox Code Playgroud)

c++ lifetime initializer-list const-reference c++11

4
推荐指数
1
解决办法
698
查看次数

关于const 引用(和const 指针)的弱语义

这可能已经被问到了。

为什么允许向非常量变量分配对常量的引用?

为什么这是允许的

int mut {0};
const int & r_to_c {mut};
mut = 1;
// now r_to_c changed to 1!
// But it was supposed to be a reference to something constant!
Run Code Online (Sandbox Code Playgroud)

?

当然,我不能改变引用到常量本身的值。我不能

r_to_c = 2;
Run Code Online (Sandbox Code Playgroud)

但是是不是const执行的资格太少了?我希望,从 const-ness 的承诺来看,不允许绑定到可变变量。

否则const给我什么保证?它们看起来很弱,而且这似乎很容易诱使程序员用脚射击自己。

我知道 C++ 以允许人们用脚射击自己而闻名。允许危险的事情发生我没有问题。在这种情况下,我的问题是,在这种情况下,它似乎是故意欺骗,因为const这里的语义不是人们所期望的。

我的问题是关于编译器和语言语义的问题,而不是特别关于引用的问题(我可以使用分配给非常量变量地址的常量指针来问同样的问题。像int mut{0}; const int * p_to_c{&mut};)。

为什么引用常量(或常量指针)的语义只是“你不能使用这个特定的窗口来修改你看到的东西(但如果你有其他非常量的窗口,你可以修改它)”而不是更强大的“这只能是声明为常量并且编译器保证它保持不变的东西的窗口”?


[术语说明:我使用表达式“const 引用”而不是“const 引用”,因为“const 引用”被解释为T& const- 与调用T* const“const 指针”一致 - 不存在。]

c++ constants const-reference

4
推荐指数
1
解决办法
88
查看次数

将局部变量从 lambda 返回到 const ref

const TBigType& a = [](){
    TBigType result;
    // ...
    return result;
}();

use(a); // by const ref
Run Code Online (Sandbox Code Playgroud)

可以像这样在 const ref 中捕获结果吗?

c++ lambda const-reference

3
推荐指数
1
解决办法
173
查看次数

C++ 何时使用 const 引用而不是转发引用

考虑我们需要实现一个f带有模板参数的函数T t。该函数不应同时复制t和接受rvalueslvalues,因此可能有两种实现:

template <class T>
void f(const T& t) { ... }

template <class T>
void f(T&& t) { ... }
Run Code Online (Sandbox Code Playgroud)

如果我们想改变t里面f的值或者需要保留类的值,就得使用第二个版本了。那么根据这个思路,我们何时以及为什么会选择第一个选项?

c++ const-reference forwarding-reference

3
推荐指数
1
解决办法
443
查看次数