最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c++ - Make user constructor behave like aggregate initialization - Stack Overflow

programmeradmin3浏览0评论

I wrote the following toy example

#include <iostream>

using namespace std;

struct A {
    A() { cerr << "default" << endl; }
    A(const A &a) { cerr << "copy" << endl; }
    A(A &&a) { cerr << "move" << endl; }
};

struct B {
    A a;
};

struct C {
    A a;
    C(A a): a(a) {}
};

int main() {
    B b {A()};
    cerr << "=======" << endl;
    C c {A()};
    return 0;
}

Compiling and running it gives:

default
=======
default
copy

We can see that the constructor of C creates a copy while no copy is required for the construction of B.

I have been unable to reproduce the behavior of B by defining my own constructor in the struct C. Replacing C(A a): a(a) {} by C(A a): a(forward<A>(a)) {} creates a move for instance.

Is there any way to create a constructor that mimics the aggregate initialization of B?

I wrote the following toy example

#include <iostream>

using namespace std;

struct A {
    A() { cerr << "default" << endl; }
    A(const A &a) { cerr << "copy" << endl; }
    A(A &&a) { cerr << "move" << endl; }
};

struct B {
    A a;
};

struct C {
    A a;
    C(A a): a(a) {}
};

int main() {
    B b {A()};
    cerr << "=======" << endl;
    C c {A()};
    return 0;
}

Compiling and running it gives:

default
=======
default
copy

We can see that the constructor of C creates a copy while no copy is required for the construction of B.

I have been unable to reproduce the behavior of B by defining my own constructor in the struct C. Replacing C(A a): a(a) {} by C(A a): a(forward<A>(a)) {} creates a move for instance.

Is there any way to create a constructor that mimics the aggregate initialization of B?

Share Improve this question edited Jan 19 at 18:46 Igor G 2,3618 silver badges22 bronze badges asked Jan 19 at 17:35 NanoredNanored 497 bronze badges 8
  • Do you know the rule of 0/3/5 ? – Pepijn Kramer Commented Jan 19 at 17:42
  • 2 B doesn't have a default constructor, it is an aggregate type and aggregates have their own initialization rules. – NathanOliver Commented Jan 19 at 17:46
  • @PepijnKramer I didn't know the name of this rule, but I'm not sure it would help here :/ – Nanored Commented Jan 19 at 17:54
  • @NathanOliver thanks for the terms, I don't have all the vocabulary. I hope it's still understandable – Nanored Commented Jan 19 at 17:55
  • You're right that will not help for C(A a). However C(A a): a(a) {} will always result copy constructor of A will be called. So probably you need to use C(A&& a) so it will accept a as a temporary – Pepijn Kramer Commented Jan 19 at 19:18
 |  Show 3 more comments

1 Answer 1

Reset to default 4

The usual trick here is to use a type that converts to the desired type:

struct C {
    A a;
    template<class T>
    C(T &&t): a(std::forward<T>(t)) {}
};
struct preA {
    operator A() {return {};}
};

C c(preA{});
发布评论

评论列表(0)

  1. 暂无评论