问题标签 [defaulted-functions]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
8 回答
10197 浏览

c++ - 在 C++11 中默认函数有什么意义?

C++11 增加了告诉编译器创建任何特殊成员函数的默认实现的能力。虽然我可以看到删除函数的价值,但显式默认函数的价值在哪里?只需将其留空,编译器就会这样做。

我能看到的唯一一点是,只有在不存在其他构造函数时才会创建默认构造函数:

但这真的比你现在做的更好吗?

还是我错过了一个用例?

0 投票
2 回答
459 浏览

c++ - 为什么要“默认”复制/移动构造函数或析构函数?

C++0x 允许您将某些函数指定为默认值:

这些函数的实现就像编译器生成它们一样,在大多数情况下,当您没有声明自己的函数时,通常会发生这种情况。

如果您声明任何 ctor(上述任何其他 ctor),则不会生成默认 ctor ,因此您可能需要将其默认为“将其恢复”。

但是,除非基成员或数据成员排除它们,否则类始终具有复制和移动 ctor⁠—⁠如果它们被排除,则默认实现将不起作用。一个类总是有一个 dtor。

为什么需要显式默认复制 ctor、移动 ctor 或析构函数?无论如何,隐式生成的实现不会做同样的事情吗?

0 投票
3 回答
1018 浏览

c++ - 如果一个人不知道它的参数类型,怎么能默认一个特殊的成员函数呢?

考虑这种情况:

我显式声明了一个移动构造函数,因此如果我想要一个未删除的复制构造函数,我需要显式声明一个复制构造函数。如果我想要default它,我怎样才能找到正确的参数类型?

我也对您是否遇到过在实际程序中实际出现这种情况的情况感兴趣。规范说

显式默认的函数应...

  • 具有相同的声明函数类型(除了可能不同的引用限定符以及在复制构造函数或复制赋值运算符的情况下,参数类型可能是“对非常量 T 的引用”,其中 T 是成员函数的类)就好像它已被隐式声明,

如果隐式声明的复制构造函数具有 type A &,我希望我的复制构造函数显式默认为参数 type A &。但是如果隐式声明的复制构造函数有参数类型A const&,我不想让我的显式默认的复制构造函数有参数类型A &,因为这会禁止从 const 左值复制。

我不能声明这两个版本,因为当隐式声明的函数具有参数类型A &而我的显式默认声明具有参数类型时,这将违反上述规则A const&。据我所知,只有当隐式声明是A const&,而显式声明是 时,才允许有区别A &

编辑:事实上,规范甚至说

如果一个函数在它的第一个声明中被显式默认,...

  • 在复制构造函数、移动构造函数、复制赋值运算符或移动赋值运算符的情况下,它应具有与已隐式声明的参数类型相同的参数类型。

所以我需要定义这些out-of-class(我认为这不会受到伤害,因为据我所知,唯一的区别是该函数将变得不平凡,在这些情况下很可能无论如何)

好吧,我发现如果显式声明的函数是无效的A const&,而隐式声明是A &

用户提供的显式默认函数(即,在其第一次声明后显式默认)在显式默认的位置定义;如果这样的函数被隐式定义为已删除,则程序格式错误。

这符合 GCC 正在做的事情。现在,我怎样才能实现匹配隐式声明的构造函数类型的最初目标?

0 投票
1 回答
362 浏览

c++ - 我可以在类主体中默认一个私有构造函数吗?

GCC 4.5 不允许我这样做:

它抱怨说:

错误:声明为非公共访问的“foo::foo(const foo&)”不能在类主体中默认
错误:声明为非公共访问的“foo& foo::operator=(const foo&)”不能在类中默认班体

但是,GCC 4.6 让我这样做。哪一个是正确的?

0 投票
2 回答
247 浏览

c++ - 用户定义的默认构造函数效率低吗?

几天前,在阅读标准 C++ 新闻时,我阅读了有关C++11 中的默认函数的帖子,在那篇文章中提到用户定义的构造函数比编译器生成的构造函数效率低:

用户定义的默认构造函数比编译器隐式定义的默认构造函数效率低。

继续阅读,有一个示例,其中用户定义的构造函数被标记为默认值,然后说:

显式默认构造函数比手动编程的默认构造函数更有效。

我不明白这些断言,所以我想知道:

  • 为什么用户默认构造函数(或特殊成员函数)的效率低于编译器隐式定义的构造函数?
  • 通过显式默认构造函数(或特殊成员函数)如何提高效率?
  • 我必须遵循哪些准则来选择默认构造函数(或特殊成员函数)以及效率如何影响这个决定?
0 投票
0 回答
144 浏览

c++ - 使用带有显式默认析构函数的 std::unique_ptr pimpl

定义以下类时

我收到以下错误(icpc):

/home/toolworks/gcc/4.8.2/bin/../include/c++/4.8.2/bits/unique_ptr.h(65): 错误:不允许不完整的类型 static_assert(sizeof(_Tp)>0, ^在以下期间检测到:

“void std::default_delete<_Tp>::operator()(_Tp *) const [with _Tp=FooImpl]”在第 184 行实例化“std::unique_ptr<_Tp, _Dp>::~unique_ptr() [在“/home/toolworks/gcc/4.8.2/bin/../include/c++/4.8.2/bits/shared_ptr_base.h”的第 290 行使用 _Tp=FooImpl, _Dp=std::default_delete]" 实例化“void std::_Sp_counted_ptr<_Ptr, _Lp>::_M_dispose() [with _Ptr=Foo *, _Lp=__gnu_cxx::_S_atomic]”在“/home/toolworks/gcc/4.8.2/bin/”的第 286 行。 ./include/c++/4.8.2/bits/shared_ptr_base.h" 隐式生成“std::_Sp_counted_ptr<_Ptr, _Lp>::~_Sp_counted_ptr() [with _Ptr=Foo *, _Lp=__gnu_cxx::_S_atomic]”在“/home/toolworks/gcc/4.8.2/bin/../include/c++/4.8.2/bits/shared_ptr_base.h”的第 286 行在“/home/toolworks/gcc/4.8.2/bin/../include /c++/4.8.2/bits/shared_ptr_base.h”在第 452 行对“std::_Sp_counted_ptr<_Ptr, _Lp>::_Sp_counted_ptr(_Ptr) [with _Ptr=Foo *, _Lp=__gnu_cxx::_S_atomic]”进行实例化“/home/toolworks/gcc/4.8.2/bin/../include/c++/4.8.2/bits/shared_ptr_base.h” 实例化“std::__shared_count<_Lp>::__shared_count(_Ptr) [with _Lp =__gnu_cxx::_S_atomic, _Ptr=Foo *]" 在 "/home/toolworks/gcc/4.8.2/bin/../include/c++/4.8.2/bits/shared_ptr_base.h" 的第 740 行实例化 " std::__shared_ptr<_Tp, _Lp>::__shared_ptr(_Tp1 *) [with _Tp=Foo, _Lp=__gnu_cxx::_S_atomic,_Tp1=Foo]”在“/home/toolworks/gcc/4.8.2/bin/../include/c++/4.8.2/bits/shared_ptr.h”的第113行“std::shared_ptr<_Tp> ::shared_ptr(_Tp1 *) [with _Tp=Foo, _Tp1=Foo]" at line ... of "main.cc"

但是,当我定义一个非默认析构函数时,它会编译:

Foo.h

Foo.cc

它编译。我在某些地方看到说“=default”应该编译,它与隐式默认函数不是同一个类(我是c++11的新手)。

那么,为什么第一个 Foo 不编译?

注意:我没有看到它是如何复制的,因为我询问了默认析构函数,而不是默认析构函数

0 投票
1 回答
351 浏览

c++ - =默认忽略访问说明符?

private尽管默认构造函数是(4.8.1 g++),但以下程序仍然编译得很好,我发现这很奇怪:

实际上来自标准的 8.4.2[2] (N3242)

只有当它被隐式声明为 constexpr 时,才可以将显式默认函数声明为 constexpr。如果它在第一个声明中被明确默认,

——它应该是公开的,

…………

默认说明符忽略访问规范的目的到底是什么?我觉得这可能会导致类设计器不希望用户创建默认值但在实现中需要默认构造函数的接口问题。我认为这可能是因为默认构造函数是正常public的,因此default旨在复制它 - 但这并不能回答为什么=default复制构造函数不会忽略private规范。

实际上,我无法从标准中看到它提到没有明确默认的copy/move构造函数/赋值public

0 投票
1 回答
599 浏览

c++ - 使用默认关键字时的 Visual Studio C2580

对于以下代码:

我收到一条错误消息:

错误 C2580 'S::S(void)':不允许使用多个版本的默认特殊成员函数

我不明白。我认为该错误是由模板化构造函数引起的(通过将其注释掉并编译程序来验证这一点)。

0 投票
3 回答
408 浏览

c++11 - 高效地创建 C++11 移动和复制感知结构

我正在尝试组合一个高效的 C++1x 结构,该结构可以利用高效的 std::move/copy 构造/和赋值操作。这些结构分为 2 个基本类别,POD 结构和非 POD 结构。我已经养成使用样板代码编写这些结构的习惯,但我很确定编译器在这方面可以做得比我做得更好,而且每个类都需要大量输入。我的问题是利用默认编译器操作我能做的最低限度是什么。例如,我知道,一旦我定义了一个显式构造函数,它就会抑制移动和赋值运算符的自动生成。此外,我希望没有超类的非 POD 结构具有默认析构函数,而那些从基类继承的结构具有默认的虚拟析构函数。

PAGE_DATA 结构的原始版本如下

然后,我添加了样板代码以使该数据结构能够感知移动,并且我还添加了一个显式构造函数(没有它,我不得不使用读起来不太好的大括号通过聚合初始化来初始化它)。

调用的相关简单 POD 结构如下所示:

在整理了一个现场大肠杆菌演示后,我能够验证样板做正确的事情。

0 投票
2 回答
617 浏览

c++ - 总是声明默认构造函数的优点和缺点是什么?

为每个非用户定义的构造函数声明始终默认的构造函数的优缺点是什么?

考虑一个具有用户定义构造函数的类,它不需要其他用户定义构造函数,它将是:

这样做还有其他实际的优点/缺点吗?