当前位置: 首页 > 知识库问答 >
问题:

C++中的friend函数是否可以有一个默认参数,该参数的类型具有私有析构函数?

颜霖
2023-03-14
class U{ ~U(); friend void foo(U); };
void foo(U = {});
error: 'U::~U()' is private within this context
    2 | void foo(U = {});
      |                ^

共有1个答案

暨鹭洋
2023-03-14

C++20[class.access]/8规定如下:

默认参数(9.3.3.6)中的名称在声明时被绑定,访问在该点而不是在默认参数的任何使用点被检查。函数模板和类模板的成员函数中默认参数的访问检查如13.9.1所述。

但是,[expr.call]/8说:

    null

但是仔细考虑这一点,我觉得这没有太多意义,因为它会暗示缺省参数在某种程度上是“特殊的”,我认为这不是有意的。也就是说,考虑一下:

class U {
  public:
    U() = default;
    U(const U&) = default;
  private:
    ~U() = default;
    friend void foo(U);
};
void foo(U = {}) {}

int main() {
    auto p = new U();
    foo(*p);  // line 1
    foo();    // line 2
}

在这里,MSVC同时接受第1行和第2行;考虑到[expr.call]/8要求析构函数可以从main访问,接受第1行显然是错误的。但是Clang接受第2行,拒绝第1行,这在我看来也很荒谬:我不认为标准的意图是选择使用默认参数(而不是自己提供参数)就可以免除调用者对参数类型的析构函数的访问。

如果[dcl.fct.default]/5似乎需要clang的行为,那么我认为它应该被认为是有缺陷的。

 类似资料:
  • 问题内容: 警告#1:实际上这是一个潜在的两部分:首先,私有内部类的构造函数是否具有形式参数?如果是,为什么JLS拒绝呢?如果没有,怎么/为什么不呢? 注意事项2: 此问题不用于推测。 我仅在寻找 权威 答案。 默认构造函数在JLS 8.8.9 中定义,该声明(部分说明): 除了在 非私有 内部成员类中之外,默认构造函数没有形式参数,在默认情况下,默认构造函数隐式声明一个表示该类的立即封闭实例的形

  • 我想在模板类之外定义如下所述的函数。 已经为第二个参数尝试了很多组合,它是一个模板,并且也接受默认参数。 我希望它是在类之外定义的实际得到编译器错误,如果它是简单的类型,我可以很容易地在第二个参数中提到int、浮动等。

  • 在 C++中,定义函数时可以给形参指定一个默认的值,这样调用函数时如果没有给这个形参赋值(没有对应的实参),那么就使用这个默认的值。也就是说,调用函数时可以省略有默认值的参数。如果用户指定了参数的值,那么就使用用户指定的值,否则使用参数的默认值。 所谓默认参数,指的是当函数调用中省略了实参时自动使用的一个值,这个值就是给形参指定的默认值。下面是一个简单的示例: 运行结果: 10, 3.5, # 2

  • 注意:如果friend函数只是在类中声明并在外部实现,那么Clang和GCC都会拒绝该代码。

  • 问题 你想定义一个函数或者方法,它的一个或多个参数是可选的并且有一个默认值。 解决方案 定义一个有可选参数的函数是非常简单的,直接在函数定义中给参数指定一个默认值,并放到参数列表最后就行了。例如: def spam(a, b=42): print(a, b) spam(1) # Ok. a=1, b=42 spam(1, 2) # Ok. a=1, b=2 如果默认参数是一个可修改的容器

  • 问题内容: 假设我通过创建共享对象并使用LD_PRELOAD首先加载它来替换函数。是否有可能使该功能的参数不同于原始库中的参数? 例如,如果我替换 pthread_mutex_lock ,这样它将代替参数 pthread_mutex_t 而是使用 pthread_my_mutex_t 。可能吗? 其次,除了函数之外,是否可以使用LD_PRELOAD更改结构声明?例如,可以向结构中增加一个字段。 问