【发布时间】:2010-12-24 01:05:45
【问题描述】:
我最近发现自己在 C++11 模式下在 gcc 4.5 中使用了以下宏:
#define RETURN(x) -> decltype(x) { return x; }
然后编写这样的函数:
template <class T>
auto f(T&& x) RETURN (( g(h(std::forward<T>(x))) ))
我一直这样做是为了避免不得不有效地编写两次函数体,并使函数体中的更改和返回类型保持同步(在我看来这是一场等待发生的灾难)。
问题是这种技术只适用于单行函数。所以当我有这样的事情时(复杂的例子):
template <class T>
auto f(T&& x) -> ...
{
auto y1 = f(x);
auto y2 = h(y1, g1(x));
auto y3 = h(y1, g2(x));
if (y1) { ++y3; }
return h2(y2, y3);
}
然后我必须在返回类型中添加一些可怕的东西。
此外,每当我更新函数时,我都需要更改返回类型,如果我没有正确更改它,如果幸运的话,我会得到一个编译错误,或者在更糟糕的情况下。我觉得必须将更改复制并粘贴到两个位置并保持同步并不是一个好习惯。
而且我想不出我想要在返回时进行隐式转换而不是显式转换的情况。
当然有一种方法可以让编译器推断出这些信息。编译器保守秘密的意义何在?我认为 C++11 的设计是为了不需要这样的重复。
【问题讨论】:
-
如果你有这么多使用 decltype 的函数,也许你需要重新考虑你正在编写的代码。我们在没有 decltype 的情况下存活了很长时间......
-
(你听起来好像每隔一小时就更改一次函数。)是的,如果编译器可以自动推断返回类型会很好,但它根本不存在,并且有一点你必须停止尝试成为编译器,而只是编写它接受的代码。 (是的,C++0x 减轻了很多事情,但不幸的是,它不能全力以赴。)所以只需指定返回类型。
-
我不认为所有的负面 cmets 都是合理的。 Boost 库中充满了诸如 ::return_type 之类的函数对象来解决这些问题。你真的认为必须定义一个新类来定义函数的返回类型是“可读的”吗?!我看不出不必以三种不同的方式复制相同的信息有什么难以理解的。
-
@ybungalobill:你能简单地推断出 boost 融合向量的返回类型吗?如果不是,你认为他们的设计有问题吗?如果是这样,你会怎么做?
-
引入 decltype 和惰性返回类型语法是有原因的,这是因为预先确定许多涉及转发的函数的类型是不可能或难以置信的。 @SoapBox:我以尊重的方式完全不同意。
标签: c++ c++11 return-value