p1.cpp
3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// RUN: %clang_cc1 -std=c++11 -verify %s
namespace std_example {
struct B1 {
B1(int, ...) {}
};
struct B2 {
B2(double) {}
};
int get();
struct D1 : B1 { // expected-note {{no default constructor}}
using B1::B1; // inherits B1(int, ...)
int x;
int y = get();
};
void test() {
D1 d(2, 3, 4); // OK: B1 is initialized by calling B1(2, 3, 4),
// then d.x is default-initialized (no initialization is performed),
// then d.y is initialized by calling get()
D1 e; // expected-error {{implicitly-deleted}}
}
struct D2 : B2 {
using B2::B2;
B1 b; // expected-note {{constructor inherited by 'D2' is implicitly deleted because field 'b' has no default constructor}}
};
D2 f(1.0); // expected-error {{constructor inherited by 'D2' from base class 'B2' is implicitly deleted}}
struct W {
W(int);
};
struct X : virtual W {
using W::W;
X() = delete;
};
struct Y : X {
using X::X;
};
struct Z : Y, virtual W {
using Y::Y;
};
Z z(0); // OK: initialization of Y does not invoke default constructor of X
template <class T> struct Log : T {
using T::T; // inherits all constructors from class T
~Log() { /* ... */ }
};
}
namespace vbase {
struct V {
V(int);
};
struct A : virtual V {
A() = delete; // expected-note 2{{deleted here}} expected-note {{deleted}}
using V::V;
};
struct B : virtual V { // expected-note {{no default constructor}}
B() = delete; // expected-note 2{{deleted here}}
B(int, int);
using V::V;
};
struct C : B { // expected-note {{deleted default constructor}}
using B::B;
};
struct D : A, C { // expected-note {{deleted default constructor}} expected-note {{deleted corresponding constructor}}
using A::A;
using C::C;
};
A a0; // expected-error {{deleted}}
A a1(0);
B b0; // expected-error {{deleted}}
B b1(0);
B b2(0, 0);
C c0; // expected-error {{deleted}}
C c1(0);
C c2(0, 0); // expected-error {{deleted}}
D d0; // expected-error {{deleted}}
D d1(0);
D d2(0, 0); // expected-error {{deleted}}
}
namespace vbase_of_vbase {
struct V { V(int); };
struct W : virtual V { using V::V; };
struct X : virtual W, virtual V { using W::W; };
X x(0);
}
namespace constexpr_init_order {
struct Param;
struct A {
constexpr A(Param);
int a;
};
struct B : A { B(); using A::A; int b = 2; };
// Construct a situation where a value can be observed to change during
// constant evaluation in C++11: value-initialization of Wrap2 performs
// zero-initialization and then calls the constructor.
struct Wrap1 : B { constexpr Wrap1(); };
struct Wrap2 : Wrap1 {};
extern const Wrap2 b;
struct Param {
constexpr Param(int c) : n(4 * b.a + b.b + c) {}
int n;
};
constexpr A::A(Param p) : a(p.n) {}
constexpr Wrap1::Wrap1() : B(1) {}
constexpr Wrap2 b = {};
constexpr B c(1);
static_assert(b.a == 1, "p should be initialized before B() is executed");
static_assert(c.a == 7, "b not initialized properly");
}
namespace default_args {
// We work around a defect in P0136R1 where it would reject reasonable
// code like the following:
struct Base {
Base(int = 0);
};
struct Derived : Base {
using Base::Base;
};
Derived d;
// FIXME: Once a fix is standardized, implement it.
}