是否可以通过引用传递的参数 return 引用?
Is it possible to return a reference via an argument passed by reference?
我想从函数中 return 布尔值或 success/failure 枚举并通过引用修改参数。但是,我想在调用函数中构造一个引用而不是复制值。
我有一些容器(比如 'example_q' 类型 std::queue)。 queue.front() 将 return 对存储在队列中的值的引用。我可以制作该引用的副本(示例 A),或者我可以引用该引用(示例 B),允许该值保留在队列中但在队列外使用。
A)
int a = example_q.front();
B)
int& b = example_q.front();
利用这个差异我还可以 return 排队的值:
A)
int get_front()
{
int a = example_q.front();
return a;
}
B)
int& get_front()
{
return example_q.front();
}
使用选项 'B' 我可以避免不必要的复制,而无需通过 std::move() 语义将数据移出队列。
我的问题是,我可以通过引用传递的参数来实现 'B' 吗?我需要以某种方式使用 std::move()/rvalues/&& 吗?
void get_front(int& int_ref)
{
// somehow don't copy the value into referenced int_ref, but construct
// a reference in the caller based on an input argument?
int_ref = example_q.front();
}
这将解决的问题是使 API 匹配修改引用参数但 return 一个 success/failure 值的其他函数,即:
if(q.get_front(referrence_magic_here))
{
...
}
我可以颠倒顺序以获得想要的结果,即:
int& get_front(bool& success)
{
...
}
但我宁愿保留 API 的模式,并且如果可能的话,能够通过 if() 语句中的一行来完成。
可能是这样的:
bool get_front(int&& int_rvalue)
{
...
int_rvalue = example_q.front();
...
return true_or_false;
}
void calling_func()
{
...
if(get_front(int& magical_ref))
{
... //use magical_ref here?
}
...
}
不,你不能那样做。
除了在它的初始化器中,引用的行为与它所指的事物一样。通过将其作为函数参数传递,您 "hide" 来自想要进行分配的部分的初始化程序。因此,函数无法访问事物的引用行为。
如果你想这样做,你将不得不使用指针:
void get_front(int*& int_ptr)
{
int_ptr = &example_q.front();
}
int* ptr = nullptr;
get_front(ptr);
// optional:
int& ref = *ptr;
(呃!)
选项 B 很好。
此代码无效 C++:
if(get_front(int& magical_ref))
您不能在将新变量传递给函数时声明它。而且因为必须同时声明和初始化引用变量,所以不可能通过将引用传递给函数来初始化引用。
你可以但是,这样做:
if(int &magical_ref = get_front()) {
但请注意,您将检查 magical_ref
是否为 0,这与示例中的条件不同。
如果您的逻辑就像比较 int
一样简单,您可以这样做:
if (int& magical_ref = get_front(); magical_ref == 42)
您可以 return std::tuple<int&, /* status condition */>
并查看状态。例如:
std::tuple<int&, bool> get_front() {
static int example = 0;
return {example, false};
}
...
// C++17's structured bindings + if statement with initializer
if (auto [ref, success] = get_front(); success) {
ref = 42;
}
我想从函数中 return 布尔值或 success/failure 枚举并通过引用修改参数。但是,我想在调用函数中构造一个引用而不是复制值。
我有一些容器(比如 'example_q' 类型 std::queue)。 queue.front() 将 return 对存储在队列中的值的引用。我可以制作该引用的副本(示例 A),或者我可以引用该引用(示例 B),允许该值保留在队列中但在队列外使用。
A)
int a = example_q.front();
B)
int& b = example_q.front();
利用这个差异我还可以 return 排队的值:
A)
int get_front()
{
int a = example_q.front();
return a;
}
B)
int& get_front()
{
return example_q.front();
}
使用选项 'B' 我可以避免不必要的复制,而无需通过 std::move() 语义将数据移出队列。
我的问题是,我可以通过引用传递的参数来实现 'B' 吗?我需要以某种方式使用 std::move()/rvalues/&& 吗?
void get_front(int& int_ref)
{
// somehow don't copy the value into referenced int_ref, but construct
// a reference in the caller based on an input argument?
int_ref = example_q.front();
}
这将解决的问题是使 API 匹配修改引用参数但 return 一个 success/failure 值的其他函数,即:
if(q.get_front(referrence_magic_here))
{
...
}
我可以颠倒顺序以获得想要的结果,即:
int& get_front(bool& success)
{
...
}
但我宁愿保留 API 的模式,并且如果可能的话,能够通过 if() 语句中的一行来完成。
可能是这样的:
bool get_front(int&& int_rvalue)
{
...
int_rvalue = example_q.front();
...
return true_or_false;
}
void calling_func()
{
...
if(get_front(int& magical_ref))
{
... //use magical_ref here?
}
...
}
不,你不能那样做。
除了在它的初始化器中,引用的行为与它所指的事物一样。通过将其作为函数参数传递,您 "hide" 来自想要进行分配的部分的初始化程序。因此,函数无法访问事物的引用行为。
如果你想这样做,你将不得不使用指针:
void get_front(int*& int_ptr)
{
int_ptr = &example_q.front();
}
int* ptr = nullptr;
get_front(ptr);
// optional:
int& ref = *ptr;
(呃!)
选项 B 很好。
此代码无效 C++:
if(get_front(int& magical_ref))
您不能在将新变量传递给函数时声明它。而且因为必须同时声明和初始化引用变量,所以不可能通过将引用传递给函数来初始化引用。
你可以但是,这样做:
if(int &magical_ref = get_front()) {
但请注意,您将检查 magical_ref
是否为 0,这与示例中的条件不同。
如果您的逻辑就像比较 int
一样简单,您可以这样做:
if (int& magical_ref = get_front(); magical_ref == 42)
您可以 return std::tuple<int&, /* status condition */>
并查看状态。例如:
std::tuple<int&, bool> get_front() {
static int example = 0;
return {example, false};
}
...
// C++17's structured bindings + if statement with initializer
if (auto [ref, success] = get_front(); success) {
ref = 42;
}