gpt4 book ai didi

c++ - 有没有办法从函数返回新对象或对现有对象的引用?

转载 作者:行者123 更新时间:2023-11-30 01:01:39 24 4
gpt4 key购买 nike

我正在尝试编写一个函数,它可以返回对作为第一个参数传递的现有对象的引用(如果它处于正确的状态),或者使用作为第二个参数传递的文字创建并返回一个新对象(默认)。

如果一个函数不仅可以接受文字,还可以接受另一个现有对象作为第二个(默认)参数并返回对其的引用,那就更好了。

下面是一个简单的实现,但它做了很多不必要的工作:

  1. 如果使用左值作为第二个(默认)参数调用,它将调用选择返回的参数的复制构造函数。理想情况下,应该返回对对象的引用。

  2. 如果使用文字作为第二个(默认)参数调用,它将调用构造函数、复制构造函数和析构函数,即使未选择第二个(默认)参数返回。如果在不调用复制构造函数或析构函数的情况下构造一个对象并将其作为右值引用返回,那就更好了。

std::string get_or_default(const std::string& st, const std::string& default_st) {
if (st.empty()) return default_st
else return st;
}

有没有一种方法可以更有效地完成此任务,同时仍然对调用者保持简单?如果我是正确的,这需要一个函数根据函数内部做出的运行时决策来更改返回类型,但我无法为调用者想到一个简单的解决方案。

最佳答案

我不能 100% 确定我理解了要求的组合,但是:

#include <iostream>
#include <string>
#include <type_traits>

// if called with an rvalue (xvalue) as 2:nd arg, move or copy
std::string get_or_default(const std::string& st, std::string&& default_st) {
std::cout << "got temporary\n";
if(st.empty())
return std::move(default_st); // rval, move ctor
// return std::forward<std::string>(default_st); // alternative
else
return st; // lval, copy ctor
}

// lvalue as 2:nd argument, return the reference as-is
const std::string& get_or_default(const std::string& st,
const std::string& default_st) {
std::cout << "got ref\n";
if(st.empty()) return default_st;
else return st;
}

int main() {
std::string lval = "lval";

// get ref or copy ...
decltype(auto) s1 = get_or_default("", "temporary1");
decltype(auto) s2 = get_or_default("", std::string("temporary2"));
decltype(auto) s3 = get_or_default("", lval);

std::cout << std::boolalpha;
std::cout << std::is_reference_v<decltype(s1)> << "\n";
std::cout << std::is_reference_v<decltype(s2)> << "\n";
std::cout << std::is_reference_v<decltype(s3)> << "\n";
}

输出:

got temporary
got temporary
got ref
false
false
true

编辑:在 OP:s 测试后制作了一个稍微更通用的版本。它可以使用 lambda,例如
auto empty_check = [](const std::string& s) { return s.empty(); };
测试第一个参数是否为空。

template<typename T, typename F>
T get_or_default(const T& st, T&& default_st, F empty) {
if(empty(st)) return std::move(default_st);
// return std::forward<T>(default_st); // alternative
else return st;
}

template<typename T, typename F>
const T& get_or_default(const T& st, const T& default_st, F empty) {
if(empty(st)) return default_st;
else return st;
}

关于c++ - 有没有办法从函数返回新对象或对现有对象的引用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58739525/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com