5

我正在编写一些函数的返回类型相当复杂的代码。我想使用autofor 从返回类型推导,但这在前向声明中显然是不可能的。所以我希望至少只复制 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()

4

1 回答 1

8

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

[...]如果函数声明器包含一个尾随返回类型(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

这与这里发生的事情相反,但它确实进一步说明这是不允许的

于 2017-09-29T18:25:57.913 回答