尾随返回类型和返回类型推断之间的冲突

The*_*Vee 5 c++ function return-type auto trailing-return-type

我正在写一些代码,其中函数的返回类型相当复杂.我想利用auto从退货类型中推断,但在前瞻性声明中这显然是不可能的.所以我希望至少只复制return语句的内容并执行以下操作,

int q = 5; // veeery complicated type

/* Declaration - the best we can do */
auto f() -> decltype(q);

/* Later, in a different file */    
auto f() {
  return q;
}
Run Code Online (Sandbox Code Playgroud)

这会在GCC 7中产生以下错误,

error: ambiguating new declaration of ‘auto f()’
note: old declaration ‘int f()’
Run Code Online (Sandbox Code Playgroud)

我当然可以重复一遍

auto f() -> decltype(q) {
  return q;
}
Run Code Online (Sandbox Code Playgroud)

在定义(有效)中,但为什么我需要在return语句中唯一给出返回类型时?f我的定义中的类型最终是多么模糊不清int f()

Nat*_*ica 8

这里的问题是跟踪返回与纯推导的返回类型不同.在[dcl.spec.auto]/2中

[...]如果函数声明包含trailing-return-type(8.3.5),则指定函数的声明返回类型

所以

auto f() -> decltype(q);
Run Code Online (Sandbox Code Playgroud)

是真的

int f();
Run Code Online (Sandbox Code Playgroud)

这与...不同

auto f()
Run Code Online (Sandbox Code Playgroud)

还有[dcl.spec.auto]/13

具有使用占位符类型的声明返回类型的函数或函数模板的重新声明或特化也应使用该占位符,而不是推导类型.[例如:

auto f();
auto f() { return 42; }  // return type is int
auto f();                // OK
int f();                 // error, cannot be overloaded with auto f()
decltype(auto) f();      // error, auto and decltype(auto) don’t match
Run Code Online (Sandbox Code Playgroud)

这与此处发生的情况相反,但它确实进一步证明了这是不允许的