看看这个:
template<class T>
struct X
{
private:
T value_;
public:
X():value_(T()) {}
X(T value):value_(value) {}
T getValue() const
{
return value_;
}
static const T value = 0; //this is dummy
template<class D, class U>
friend decltype(X<D>::value + X<U>::value) operator + (X<D> lhs, X<U> rhs);
};
template<class T, class U>
decltype(X<T>::value + X<U>::value) operator + (X<T> lhs, X<U> rhs)
{
return lhs.getValue() + rhs.getValue();
/* THIS COMPILES WITH VS2010 but line below doesn't which is incorrect
* behaviour in my opinion because: friendship has been declared and
* access to private data should be granted.*/
return lhs.value_ + rhs.value_; //THIS COMPILES WITH GCC 4.6
}
在这样的例子之后肯定会有问题(顺便说一句,整个例子按预期编译和工作),无论如何这里是问题:
我们真的必须使用带有延迟返回类型的丑陋语法吗?正如我在这个例子中所证明的那样,它可以“以正常方式”完成。
已编辑(现在没有这个可怕的静态假人 - 所有的人都在唱歌跳舞)
template<class T>
struct X
{
private:
T value_;
public:
typedef T value_type;
X():value_(T()) {}
X(T value):value_(value) {}
T getValue()const { return value_; }
template<class D, class U>
friend X<decltype(typename X<D>::value_type() + typename X<U>::value_type())> operator + (X<D> lhs, X<U> rhs);
};
template<class T, class U>
X<decltype(typename X<T>::value_type() + typename X<U>::value_type())> operator + (X<T> lhs, X<U> rhs)
{
return lhs.getValue() + rhs.getValue();
//return lhs.value_ + rhs.value_; //VS is __wrong__ not allowing this code to compile
}
最佳答案
有时如果没有尾随返回类型它就无法工作,因为编译器无法知道程序员要求它做什么或涉及的类型是什么。
以这个简单的 forwarding-wrapper 模板函数为例(这不是虚构的示例,而是取 self 不久前编写的一些真实代码):
template<typename T, typename... A> auto fwd(T fp, A...a) -> decltype(fp(a...))
{
// some other code
return fp(a...);
};
可以使用具有任何类型未知返回类型的任何类型的未知函数指针调用此函数。它会起作用,它会返回正确的类型,并且不会混淆编译器。
如果没有尾随返回类型,编译器将无法弄清楚发生了什么。
您可以使用 #define
并滥用逗号运算符来获得类似的效果,但是呃......以什么代价。
关于c++ - 为什么我们必须有延迟返回类型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5895492/