Date: Thu, 18 Aug 2022 14:56:57 -0700
With appropriate syntax, perhaps a user-defined constructor could be used
in addition to designated/aggregate initialization? A constructor with a
member initializer for each member followed by a body is similar to a
designated initializer construction followed by a method call, perhaps that
could be fused into a single statement? For example:
struct S {
int a;
S(int a) : a(a) { std::cout << "constructed an S instance: " << a <<
std::endl; };
};
int main() {
S s(1);
};
could be equivalent to
struct S {
int a;
S() /* some tag that designates this constructor as "the
aggregate/designated initializer constructor" */ { std::cout <<
"constructed an S instance: " << a << std::endl; };
};
int main() {
S s = S{.a = 1};
};
In other words, adding the appropriate tag to a constructor means a) this
class supports designated/aggregate initialization despite whatever other
special member functions, and b) when designated/aggregate initialization
is used, the body of this constructor is executed after all members are
initialized (note: this would imply that the tagged constructor must have
no arguments and no member initializers of its own, otherwise compile
error).
Base class initialization in case of inheritance seems like it should work
"fine", the existing mechanisms for designated/aggregate initializing base
classes seems like they should follow naturally.
On Thu, Aug 18, 2022 at 2:42 PM Brian Bi via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> I don't think an attribute would be appropriate for this. With attributes
> a design principle is that the implementation should still be considered
> conforming if it ignores the attribute. Presumably you want to write
> portable code using your proposed feature, but if it were an attribute,
> then compilers could refuse to compile it by not supporting the attribute.
>
> I am not aware of any proposals for this feature, but IMHO it is worth
> exploring. Scott Meyers explained
> <http://scottmeyers.blogspot.com/2014/03/a-concern-about-rule-of-zero.html>
> that if, for example, you want to add logging to your class's destructor,
> then suddenly you're forced to explicitly default the move constructor, and
> as soon as you do that, your program will stop compiling if it employs
> aggregate initialization. It is not possible to perfectly emulate aggregate
> initialization using a user-written constructor, particularly now that we
> have designated initializers. Having a way to explicitly opt in to
> aggregate initialization is the only way I can see to solve this problem.
>
> On Thu, Aug 18, 2022 at 5:27 PM Ivan Matek via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> Often I encounter the following problem:
>> I am happily using the readability benefit of designated initializers in
>> my struct.
>> Then I notice I must add a functionality that makes it a nonaggregate
>> (for example deleting copy constructor to prevent accidental expensive
>> copy), then all my nice initialization must go away and I am forced to
>> write a spammy "forwarding" constructor (one that does nothing, just
>> initializes all variables with mathiing arguments).
>>
>> I am not sure what syntax would be best, maybe
>> [[agg_init]]
>> attribute?
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>
>
> --
> *Brian Bi*
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
in addition to designated/aggregate initialization? A constructor with a
member initializer for each member followed by a body is similar to a
designated initializer construction followed by a method call, perhaps that
could be fused into a single statement? For example:
struct S {
int a;
S(int a) : a(a) { std::cout << "constructed an S instance: " << a <<
std::endl; };
};
int main() {
S s(1);
};
could be equivalent to
struct S {
int a;
S() /* some tag that designates this constructor as "the
aggregate/designated initializer constructor" */ { std::cout <<
"constructed an S instance: " << a << std::endl; };
};
int main() {
S s = S{.a = 1};
};
In other words, adding the appropriate tag to a constructor means a) this
class supports designated/aggregate initialization despite whatever other
special member functions, and b) when designated/aggregate initialization
is used, the body of this constructor is executed after all members are
initialized (note: this would imply that the tagged constructor must have
no arguments and no member initializers of its own, otherwise compile
error).
Base class initialization in case of inheritance seems like it should work
"fine", the existing mechanisms for designated/aggregate initializing base
classes seems like they should follow naturally.
On Thu, Aug 18, 2022 at 2:42 PM Brian Bi via Std-Proposals <
std-proposals_at_[hidden]> wrote:
> I don't think an attribute would be appropriate for this. With attributes
> a design principle is that the implementation should still be considered
> conforming if it ignores the attribute. Presumably you want to write
> portable code using your proposed feature, but if it were an attribute,
> then compilers could refuse to compile it by not supporting the attribute.
>
> I am not aware of any proposals for this feature, but IMHO it is worth
> exploring. Scott Meyers explained
> <http://scottmeyers.blogspot.com/2014/03/a-concern-about-rule-of-zero.html>
> that if, for example, you want to add logging to your class's destructor,
> then suddenly you're forced to explicitly default the move constructor, and
> as soon as you do that, your program will stop compiling if it employs
> aggregate initialization. It is not possible to perfectly emulate aggregate
> initialization using a user-written constructor, particularly now that we
> have designated initializers. Having a way to explicitly opt in to
> aggregate initialization is the only way I can see to solve this problem.
>
> On Thu, Aug 18, 2022 at 5:27 PM Ivan Matek via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
>
>> Often I encounter the following problem:
>> I am happily using the readability benefit of designated initializers in
>> my struct.
>> Then I notice I must add a functionality that makes it a nonaggregate
>> (for example deleting copy constructor to prevent accidental expensive
>> copy), then all my nice initialization must go away and I am forced to
>> write a spammy "forwarding" constructor (one that does nothing, just
>> initializes all variables with mathiing arguments).
>>
>> I am not sure what syntax would be best, maybe
>> [[agg_init]]
>> attribute?
>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>
>
> --
> *Brian Bi*
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>
Received on 2022-08-18 21:57:08