【问题标题】:Clash between trailing return type and return type deduction尾随返回类型和返回类型扣除之间的冲突
【发布时间】:2018-03-11 16:57:55
【问题描述】:

我正在编写一些函数的返回类型相当复杂的代码。我想使用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() 更加模棱两可?

【问题讨论】:

  • 不是标准大师,但是如果根据您对函数的实际定义,尾随类型和auto 推导类型不匹配,编译器应该怎么做?我认为这就是 gcc 报告它的原因。
  • 我希望它只是告诉我它不匹配。两种类型是否相同应该很容易回答。但是既然你提到了这一点,很有趣的是int f(); long f() { return 1; }产生的错误措辞是一样的!
  • 我同意你的看法。我还想知道是否有任何标准参考明确指出auto-推断的返回类型不能与具体的返回类型函数折叠(即使它们匹配)。

标签: c++ function return-type auto trailing-return-type


【解决方案1】:

这里的问题是尾随返回与纯粹推导的返回类型不同。在 [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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-09-10
    • 1970-01-01
    • 2011-11-07
    • 2017-08-02
    • 2020-02-19
    相关资源
    最近更新 更多