C++ 11增加了告诉编译器创建任何特殊成员函数的默认实现的能力.虽然我可以看到删除函数的价值,但显式默认函数的值是什么?只需将其留空,编译器无论如何都会这样做.
我能看到的唯一一点是,只有当没有其他构造函数存在时才会创建默认构造函数:
class eg {
public:
eg(int i);
eg() = default;
};
Run Code Online (Sandbox Code Playgroud)
但这真的比你现在这样做好吗?
class eg {
public:
eg(int i);
eg() {}
};
Run Code Online (Sandbox Code Playgroud)
或者我错过了一个用例?
我发现很奇怪,尽管默认构造函数是private(4.8.1 g ++),但下面的程序仍然编译得很好:
class A{
private:
A() = default;
A(const A&) = default;
};
int main(){
A a;
}
Run Code Online (Sandbox Code Playgroud)
实际上从标准的8.4.2 [2](N3242)
显式默认函数只有在被隐式声明为constexpr时才可以声明为constexpr.如果在第一次声明中明确违约,
- 它应该是公开的,
..........
默认说明符忽略访问规范的目的究竟是什么?我觉得这可能会导致类设计者不希望用户创建默认值但需要实现中的默认构造函数的接口问题.我想也许是因为默认构造函数是正常的public,所以default复制它的目的 - 但这并不能解释为什么=default复制构造函数不会忽略private规范.
class A{
private:
A() = default;
A(const A&) = default;
};
int main(){
A a;
A b(a); //error: constexpr A::A(const A&) is private
}
Run Code Online (Sandbox Code Playgroud)
实际上我无法从标准中看到它提到明确默认的copy/move构造函数/赋值没有public.
GCC 4.5不允许我这样做:
class foo {
public:
foo() = default;
private:
foo(foo const&) = default;
foo& operator=(foo const&) = default;
};
Run Code Online (Sandbox Code Playgroud)
它抱怨说:
错误:使用非公共访问声明的'foo :: foo(const foo&)'在类体
错误中无法默认:使用非公共访问声明的'foo&foo :: operator =(const foo&)'不能默认为阶级身体
但是,GCC 4.6让我这样做.哪一个是正确的?
几天前,在阅读标准C++新闻时,我读过有关C++ 11中默认函数的帖子,在那篇文章中提到用户定义的构造函数效率低于编译器生成的函数:
用户定义的默认构造函数的效率低于编译器隐式定义的默认构造函数.
继续阅读,有一个例子,用户定义的构造函数被标记为默认值,然后说:
显式默认构造函数比手动编程的默认构造函数更有效.
我不明白这些断言,所以我想知道:
Clang 编译得很好,但 GCC 和 MSVC 抱怨不能operator=默认:
#include <type_traits>
template<class T>
struct S
{
typedef typename std::enable_if<!std::is_enum<T>::value, S>::type Me;
S &operator=(Me const &) = default;
};
int main()
{
S<int> s1, s2;
s1 = s2;
}
Run Code Online (Sandbox Code Playgroud)
这段代码合法吗?如果不是,那么Me定义为是否合法typedef S Me;?
C++ 0x允许您将某些函数指定为默认值:
struct A {
A() = default; // default ctor
A(A const&) = default; // copy ctor
A(A&&) = default; // move ctor
A(Other); // other ctor
~A() = default; // dtor
A& operator=(A const&) = default; // copy assignment
A& operator=(A&&) = default; // move assignment
};
Run Code Online (Sandbox Code Playgroud)
这些函数的实现与编译器生成它们的情况相同,这种情况通常在您未声明自己的情况下在大多数情况下发生.
如果您声明任何ctor(上述任何其他ctor),则不会生成默认ctor ,因此您可能需要将其默认为"将其恢复".
但是,除非基类或数据成员排除它们,否则类总是有一个副本并移动它们 - 如果它们被排除,则默认实现将不起作用.一个班级总是有一个dtor.
为什么需要显式默认复制ctor,移动ctor或析构函数?无论如何,隐式生成的实现不会做同样的事情吗?
cppreference显示以下定义std::in_place_t:
struct in_place_t {
explicit in_place_t() = default;
};
inline constexpr std::in_place_t in_place{};
Run Code Online (Sandbox Code Playgroud)
他们为什么要添加一个explicit默认的构造函数?为什么不排除它?有什么好处?
我对在C++ 11和C++ 17中如何/为什么调用构造函数感到困惑.
#include <iostream>
using namespace std;
//---
template<typename T>
struct StructTest
{
public:
const T Var = -1;
//---
// constexpr StructTest() = delete; // 1
// constexpr StructTest() = default; // 2
// constexpr StructTest(const StructTest &Source) = delete; // 3
// constexpr StructTest(const StructTest &Source) = default; // 4
// constexpr StructTest(const StructTest &Source) {cout << "Copy" << endl;}; // 5
};
//---
StructTest<int> A{};
StructTest<int> A1{1};
StructTest<int> A2(A);
//---
int main(void)
{
return(0);
};
Run Code Online (Sandbox Code Playgroud)
所以当我取消注释某些行的组合(并使用带有clang的c …
c++ defaulted-functions deleted-functions list-initialization
在下面的示例中,struct A没有默认构造函数。因此,从它继承的struct B和 都struct C无法获得编译器生成的默认构造函数:
struct A {
A(int) {}
};
struct B : A {
B() = default; //#1
};
struct C : A {
C();
};
C::C() = default; //#2
Run Code Online (Sandbox Code Playgroud)
#1. 在 中struct B,默认的默认构造函数在类内部声明,并且所有编译器都接受它,只有 Clang 显示警告说:explicitly defaulted default constructor is implicitly deleted [-Wdefaulted-function-deleted]
#2. 但是在外部声明的默认构造函数struct C会生成编译器错误。演示: https: //gcc.godbolt.org/z/3EGc4rTqE
为什么默认构造函数的位置很重要:在类内部还是外部?
为每个非用户定义的构造函数声明始终默认的构造函数有什么利弊?
考虑一个具有用户定义的构造函数的类,该构造函数不需要其他用户定义的构造函数,它将是:
class Foo
{
public:
Foo() { // user-defined declaration }
Foo(const Foo&) = default;
Foo(Foo&&) noexcept = default;
~Foo() = default;
Foo& operator=(const Foo&) = default;
Foo& operator=(Foo&&) = default;
}
Run Code Online (Sandbox Code Playgroud)
这样做有其他实际的优点/缺点吗?