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.
}
|