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

时间:2017-09-29 18:13:08

标签: 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;
}

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

error: ambiguating new declaration of ‘auto f()’
note: old declaration ‘int f()’

当然我可以重复

auto f() -> decltype(q) {
  return q;
}

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

1 个答案:

答案 0 :(得分:8)

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

  

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

所以

auto f() -> decltype(q);

真的是

int f();

不同
auto f()

还有[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

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