【问题标题】:Compiler error when declaring a friend function with a typedef'ed return type使用 typedef 的返回类型声明友元函数时出现编译器错误
【发布时间】:2020-04-27 09:20:30
【问题描述】:

小例子:

#include <cstdint>

std::int32_t someFunc();

namespace foo
{
class FooClass
{
private:
    void bar(){}
    friend std::int32_t ::someFunc();
};
}

std::int32_t someFunc()
{
    foo::FooClass c;
    c.bar();
    return 0;
}


int main(int argc, const char * argv[])
{
    return someFunc();
}

构建此代码会导致以下错误: pathTo/fooClass.hpp:8:17: 'int32_t' (aka 'int') 不是类、命名空间或枚举

其他感兴趣的信息:

  • 由于解析友元声明失败,编译器还抱怨 bar() 是私有的,这是意料之中的。
  • 如果您将朋友声明更改为“friend int ::someFunc();”示例代码无需任何其他更改即可编译。
  • 声明“typedef int myInt;”并且在朋友声明中使用 myInt 作为返回类型也无法编译并出现相同的错误。
  • 似乎不是特定于平台的:MacOS 和 Android 工具链都会出现

所以这似乎与朋友声明中的返回类型是 typedef 的事实有关,但我不明白为什么会出现问题。有人能解释一下为什么上面的代码不能编译吗?

编辑:通常情况下,我意识到问题所在为时已晚。编译器正在解析此代码,就好像 someFunc 是 std::int32_t 的成员,这确实不是有效的语法。所以我的新问题是,在这样的情况下,如何在朋友声明中 :: 必须在 someFunc 之前进行朋友声明才能正确解析?

【问题讨论】:

  • I can't replicate your problem 与您显示的代码。你如何构建你的程序?构建时是否有更多输出(如任何信息说明)?
  • 我可以使用 Clang 进行复制。并在我删除范围运算符 :: 时修复它,如 friend std::int32_t someFunc(); 可能是 Clang 中的错误。
  • 请创建一个minimal reproducible example 来演示没有:: 的情况下它是如何失败的。
  • 是的,我正在使用 Xcode 用 clang 构建。我没有尝试过没有 :: 的 gcc @Yunnosch 编译器抱怨 bar 是一个私有函数,这意味着友元函数与实现不正确匹配。

标签: c++ compiler-errors typedef friend


【解决方案1】:

不确定是否是错误。但是当涉及到声明中的歧义时,解决方案通常是正确使用括号。您可以如下修改您的朋友声明

friend std::int32_t (::someFunc)();

这将强制范围解析运算符正确绑定到声明符 id 而不是类型。

Live example

声明符的某些部分(甚至只是 id)通常可以用括号括起来,有时它们需要加上括号才能获得正确的含义。例如,返回指针的函数和指向函数的指针之间的古老区别

int *foo();
int (*bar)();

【讨论】:

    猜你喜欢
    • 2010-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多