How to prevent direct public creation of a struct?

Brad Anderson eco at gnuk.net
Thu May 3 14:46:53 PDT 2012


On Thursday, 3 May 2012 at 21:36:53 UTC, Nick Sabalausky wrote:
> I want to do something like this:
>
> ------------------------------------------
> module moduleFoo;
>
> // Only allow certain values of "str"
> template foo(string str)
> {
>     static assert(str == "a" || str == "b" || str == "c");
>     immutable foo = Foo(str);
> }
>
> struct Foo
> {
>     // Only "a", "b", and "c" should be allowed,
>     // checked at compile-time via "template foo".
>     // Also, not modifyable.
>     private string _str;
>     @property string str()
>     {
>         return _str;
>     }
> }
> ------------------------------------------
>
> I want struct Foo itself to be public, but I want to *force* 
> all code
> outside moduleFoo to *create* Foo via the "foo" template. 
> Copying should be
> allowed though. Ie:
>
> ------------------------------------------
> auto a = foo!"a"; // ok
> a.str = "b"; // Error: str is a read-only property
> auto z = foo!"z"; // Error: fails static assert
> auto a2 = a; // Copy it: ok
>
> auto b = Foo("b"); // Error: I want to *force* the usage of 
> "template foo"
>
> Foo x; // Kinda ambivalent about this: I'd prefer if it were 
> disallowed, but
> I don't think that's possible. If it's indeed impossible, I 
> know I can just
> declare Foo.str as (string str = "a";) so that's not a big 
> problem.
> ------------------------------------------
>
> The *key* thing here that I'm not sure how to do is: How do I 
> disallow
> this?:
>
> auto b = Foo("b"); // Error: I want to *force* the usage of 
> "template foo"

I would have thought adding a private this(string str) 
constructor would work but then foo can't be called from a 
separate module ("privcons.d(5): Error: struct privcons.Foo 
member this is not accessible" which is the same but desirable 
error it gives if you do "auto b = Foo("b");").  I thought all 
module members had access to private members of the same module 
but I guess that's not the case with template functions.


More information about the Digitalmars-d-learn mailing list