c++ - 在 C++ 中通过引用传递变量的地址
问题描述
void test(const int*& in){}
int main(){
int a = 5;
test(&a);
return 0;
}
上面的代码不编译说cannot bind non-const lvalue reference of type 'const int*&' to an rvalue of type 'const int*'
。如果我进行此更改,它会按预期工作:
int a = 5;
const int *b = &a; // `const` has to be specified here. why?
test(b);
我有两个问题:
1-为什么我的第一个示例不起作用?如果可以像这样传递常规常量:
void test(const int& in){}
int main(){
test(5);
return 0;
}
5
没有参考,C++ 在幕后为我创建一个临时变量。为什么在通过引用传递指针的情况下不做同样的事情?
2-为什么我必须在const
上面指定int *b
才能编译?因为我不必将它放在常规整数引用的情况下?即这很好用:
void test(const int& in){}
int main(){
int a = 5; // no `const` added.
test(a);
return 0;
}
解决方案
1-为什么我的第一个示例不起作用?
该参数是对指向 const 的指针的引用。&a
- 这是参数 - 是指向非常量的指针。指向 const 的指针和指向非 const 的指针是不同的类型。该参数可以隐式转换为指向 const 类型的指针。但是,该转换的结果是一个右值——它是一个临时对象。该函数的参数是对非常量的左值引用,并且此类引用不能绑定到右值1。
如果可以像这样传递常规常量:
在该示例中,您有一个对 const 的左值引用。对 const 的左值引用可以绑定到右值。在 的情况下test(a)
,被引用对象的类型甚至与引用的类型匹配,因此甚至没有转换,参数直接引用传递的参数。
为什么在通过引用传递指针的情况下不做同样的事情?
见上文1
为什么我必须在 int *b 之前指定 const 才能编译?
因为参数是指向 const 的非 const 指针的左值引用。如果你没有在那里指定 const,那么你有一个指向非 const 的指针,因此你需要一个转换,例如在的情况下&a
,因此结果将是一个右值,因此对非 const 的左值引用不能约束。
您可以通过使用对与参数类型匹配的 const 的引用来使指针函数类似于整数示例:
int* a;
// analogous to your int example:
void test1(int* const& in);
test1(&a); // OK, no conversion
// now, we have a reference to non-const,
// but that's fine since there is no conversion:
void test2(int* const& in);
test2(&a); // OK, no conversion
// now there is conversion, but that's fine since
// it is an lvalue reference to const:
void test3(const int* const& in);
test3(&a); // OK, conversion
// there's a conversion here and the reference isn't
// const but that's fine since it's an rvalue reference:
void test4(const int*&& in);
test4(&a); // OK, conversion
或者,您可以通过引入转换并使用对非常量的引用使其类似于指针示例来使整数示例失败:
long b;
// analogous to your pointer example:
void test5(int& in);
test5(b); // NOT OK
请注意,被引用的类型是指向 const 的指针还是指向非 const 的指针与引用是对 const 或非 const 的引用完全不同。
推荐阅读
- discord-jda - JDA - 如何将 EmbedMessage 作为对象获取?
- java - HttpRequest uri 无法正确解析 url
- swift - 如何处理自定义 XCTAssert 函数中的“抛出”?
- sql - 从父列 id 获取父列值
- html - 将备用行颜色应用于 ext js tpl 表
- ssis - SSIS 包 - 如何跳过已加载的文件
- django - 如何在导出之前更改 Django import_export csv 文件而不更改数据库
- go - 如何向数据访问层方法添加测试?
- node.js - 在 firebase 函数中创建 Google Cloud Task
- java - 无法从自己的类中获取 ItemStack 值