www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - initialization of structs

reply =?ISO-8859-1?Q?Christian_K=F6stlin?= <christian.koestlin gmail.com> writes:
Hi,

I have the problem, that I want to always construct a struct with a 
parameter. To make this more comfortable (e.g. provide a default 
parameter I have a factory function to create this struct).

struct S {
   int i;
   this(int i_) { i = i_; }
}

S createS(int i=5) {
   return S(i);
}

My question now is:
Is there a way to enfore the creation of the struct with createS?
Or to put it in another way. Is it possible to forbid something like:
S s; or even auto s = S(1);? I read about the this(this) thing, but that
is only used when the struct is copied, as far as I understood.


(My struct has the nature to only work if it is not constructed with the 
default struct constructor).

thank in advance

christian
Sep 26 2011
next sibling parent reply Timon Gehr <timon.gehr gmx.ch> writes:
On 09/26/2011 10:55 PM, Christian Köstlin wrote:
 Hi,

 I have the problem, that I want to always construct a struct with a
 parameter. To make this more comfortable (e.g. provide a default
 parameter I have a factory function to create this struct).

 struct S {
 int i;
 this(int i_) { i = i_; }
 }

 S createS(int i=5) {
 return S(i);
 }

 My question now is:
 Is there a way to enfore the creation of the struct with createS?
 Or to put it in another way. Is it possible to forbid something like:
 S s; or even auto s = S(1);? I read about the this(this) thing, but that
 is only used when the struct is copied, as far as I understood.


 (My struct has the nature to only work if it is not constructed with the
 default struct constructor).

 thank in advance

 christian

Starting with DMD 2.055, this works. struct S{ this() disable; this(int i_) { i = i_; } }
Sep 26 2011
parent =?ISO-8859-1?Q?Christian_K=F6stlin?= <christian.koestlin gmail.com> writes:
On 09/26/2011 11:15 PM, Timon Gehr wrote:
 On 09/26/2011 10:55 PM, Christian Köstlin wrote:
 Hi,

 I have the problem, that I want to always construct a struct with a
 parameter. To make this more comfortable (e.g. provide a default
 parameter I have a factory function to create this struct).

 struct S {
 int i;
 this(int i_) { i = i_; }
 }

 S createS(int i=5) {
 return S(i);
 }

 My question now is:
 Is there a way to enfore the creation of the struct with createS?
 Or to put it in another way. Is it possible to forbid something like:
 S s; or even auto s = S(1);? I read about the this(this) thing, but that
 is only used when the struct is copied, as far as I understood.


 (My struct has the nature to only work if it is not constructed with the
 default struct constructor).

 thank in advance

 christian

Starting with DMD 2.055, this works. struct S{ this() disable; this(int i_) { i = i_; } }

without error and outputs l: 0 c: 0 import std.stdio : writeln; struct S { private: int[] data; disable this(this); disable this(); this(size_t s) { data = new int[s]; } public: void p() { writeln("l: ", data.length); writeln("c: ", data.capacity); } static S create(size_t s = 8) { return S(s); } } unittest { auto s = S(); s.p(); } int main(string[] args) { return 0; } shouldnt this lead to a compile error? thanks in advance christian
Sep 27 2011
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
You can hide the constructor from external code by using "private
this()". And you can disable the default constructor via  disable
this();
You may also wish to make your fields private as well.

You don't necessarily have to make createS() a free function, you can
make it a static function inside of S, ala:

struct S {
     disable this();
    static S create(int _i) { return S(_i); }
private:
    int i;
    this(int i_) { i = i_; }
}

create() will not occupy any space in any of the S instances. If that
doesn't compile it's because I haven't had my coffee yet. :p
Sep 26 2011
parent =?ISO-8859-1?Q?Christian_K=F6stlin?= <christian.koestlin gmail.com> writes:
On 9/26/11 23:18 , Andrej Mitrovic wrote:
 You can hide the constructor from external code by using "private
 this()". And you can disable the default constructor via  disable
 this();
 You may also wish to make your fields private as well.

 You don't necessarily have to make createS() a free function, you can
 make it a static function inside of S, ala:

 struct S {
       disable this();
      static S create(int _i) { return S(_i); }
 private:
      int i;
      this(int i_) { i = i_; }
 }

 create() will not occupy any space in any of the S instances. If that
 doesn't compile it's because I haven't had my coffee yet. :p

thanks a lot! christian
Sep 26 2011
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 9/26/11, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:
 create() will not occupy any space in any of the S instances.

Sorry for that stupid comment. struct methods don't occupy space in struct instances regardless if they're static or not.
Sep 26 2011