C++:声明变量以保存函数返回值的最佳方式



我认为以下是一种相对常见的模式(使用的确切类型并不重要,它们只是示例(:

std::vector<std::string> manufactureVector(int param1, const std::string& param2) {
std::vector<std::string> returnValue;
// do some calculation with param1 and param2 to fill in the vector
return returnValue;
}

然而,manufactureVector的返回类型被提到了两次,具有这种冗余的所有缺点,例如,任何未来的更改都必须在两个地方进行相同的更改,等等。消除这种冗余的最佳方法是什么?我知道:

  1. 使用typedef。如果返回类型是一次性的,那么这似乎很麻烦,这样typedef就不会在其他地方使用;至少,这样的typedef添加了一行代码
  2. 我相信C++20(可能更早(允许您将类型(在函数声明中(的第一个出现更改为auto,并且它将根据实际返回的内容进行推断。但这似乎不适用于在标头中声明函数(在标头中没有可推断的主体(,然后在另一个源文件中定义它。(也许这是切换到模块的原因之一?(此外,至少在我看来,如果使用auto作为返回类型,那么很难看到manufactureVector的返回类型到底是什么:我必须找到返回语句,然后弄清楚该表达式的类型

是否还有其他可能更好的替代方案可供考虑?特别是是否存在任何合理简短的";咒语;使得

MyComplicatedType foo(int p, double q) {
Incantation returnValue;
// Here returnValue is a variable of type MyComplicatedType, whatever that type was
...
}

理想情况下,这样的咒语不必显式地使用函数名";foo";或者,因为这将替代不同的(小(冗余。

(相当(很久以前,GCC已经命名了类似的返回值

MyComplicatedType foo(int* ptr, char c) return returnValue { 
// here returnValue is a newly default-constructed variable
// of type MyComplicatedType
...
// And in fact having declared the return variable this way,
// you didn't even need to have the return statement at the end.
}

在我看来,这正是这里的门票,但不幸的是,它被留在了C++历史的垃圾箱中。有现代的等价物或替代品吗?(我对仅C++20的解决方案非常满意。(

如果函数没有重载。您不需要传递参数来获得返回类型。

template <auto F>
using return_type_of = decltype(std::function{F})::result_type;
int foo(int p){
return_type_of<foo> x;
return x;
}

*仍然需要类型foo两次btw.

**除了CCD_ 5也需要参数类型之外。

然而,两次都提到了manufactureVector的返回类型

一旦涉及依赖类型,它甚至可以不止一次:

std::vector<std::string>::iterator b, e;
for (b=returnValue.begin(), e=returnValue.end(); b != e; ++b)

或者类似的东西。

因此,现在除了这一切,这也需要改变。

auto经常来这里救援,但并非总是如此。

任何未来的更改都必须在两个地方进行相同的更改,

返回类型必须在多个位置显式拼写,这是不可避免的。这就是C++的工作原理。

然而,在大多数情况下,在两个或多个地方更改返回类型是可能的。

typedef std::vector<std::string> manufactured_vector_t;
// ...
manufactured_vector_t manufactureVector(int param1, const std::string& param2) {
manufactured_vector_t returnValue;
// ...
manufactured_vector_t::iterator b, e;
for (b=returnValue.begin(), e=returnValue.end(); b != e; ++b)
// ...
return returnValue;
}

现在,如果std::vector<std::string>不再符合要求,它只需要在一个地方更新。

很可能还需要一些其他的改变。但是,至少,这会解决这一部分。

相关内容

  • 没有找到相关文章

最新更新