Thread overview
Passing anonymous enums as function parameters
Dec 17, 2017
kerdemdemir
Dec 17, 2017
Jonathan M Davis
Dec 17, 2017
kerdemdemir
Dec 17, 2017
Jonathan M Davis
Dec 18, 2017
Jacob Carlborg
Dec 20, 2017
kerdemdemir
Dec 17, 2017
Jacob Carlborg
December 17, 2017
I have an enum statement :

enum : string
{
    KErdem
    Ali
    Zafer
    Salih
    //etc...
}


I don't want to give a name to my enum class since I am accessing this variables very often.

But I also have a function like:

double ReturnCoolNess( /* Is there any way? */ enumVal )
{
  switch (enumVal)
  {
	case KErdem:
	{
		return 0.0
	}
	case Ali:
	{
		return 100.0;	
	}
	case Salih:
	{
		return 100.0;	
	}
        // etc..
  }
}

Is there any way I still keep my enum anonymous and be able to call functions with different enumarations. Or is there any other way to call named enums without type name ?
December 17, 2017
On Sunday, December 17, 2017 11:49:58 kerdemdemir via Digitalmars-d-learn wrote:
> I have an enum statement :
>
> enum : string
> {
>      KErdem
>      Ali
>      Zafer
>      Salih
>      //etc...
> }
>
>
> I don't want to give a name to my enum class since I am accessing this variables very often.
>
> But I also have a function like:
>
> double ReturnCoolNess( /* Is there any way? */ enumVal )
> {
>    switch (enumVal)
>    {
>   case KErdem:
>   {
>       return 0.0
>   }
>   case Ali:
>   {
>       return 100.0;
>   }
>   case Salih:
>   {
>       return 100.0;
>   }
>          // etc..
>    }
> }
>
> Is there any way I still keep my enum anonymous and be able to call functions with different enumarations. Or is there any other way to call named enums without type name ?

D does not have anonymous enums. Either you're declaring an enum which creates a new type and therefore has a name and a base type, or you're just creating manifest constants that don't create a new type. e.g.

enum MyEnum : string
{
    a = "hello",
    b = "foo",
    c = "dog",
    d = "cat"
}

vs

enum string a = "hello";
enum string b = "foo";
enum string c = "dog";
enum string d = "cat";

or

enum a = "hello";
enum b = "foo";
enum c = "dog";
enum d = "cat";

If you want a function to accept values that aren't tied to a specific enum, then just have the function take the base type.

Now, within sections of code, you can use the with statement to reduce how often you have to use the enum type's name, e.g.

with(MyEnum) switch(enumVal)
{
    case a: { .. }
    case b: { .. }
    case c: { .. }
    case d: { .. }
}

but you can't have an enum without a name or just choose not to use an enum's name. With how enums work in D, there's really no point in having them if you're not going to treat them as their own type or refer to them via the enum type's name. If that's what you want to do, then just create a bunch of manifest constants.

- Jonathan M Davis

December 17, 2017
What I meant with anonymous enums was:
https://dlang.org/spec/enum.html#anonymous_enums. Maybe I couldn't explain well but I believe D have anonymous enums. I am sorry I have forgotten to remove " :string" in my example from the "enum : string". Please stretch out ": string" part my problem is not related with that.

I am not sure if it is a good one but I found a solution for my problem

double ReturnCoolNess(U)( U enumVal )
{
  switch (enumVal)
  {
	case KErdem:
	{
		return 0.0
	}
	case Ali:
	{
		return 100.0;	
	}
	case Salih:
	{
		return 100.0;	
	}
        // etc..
  }
}

ReturnCoolNess(KErdem); ---> Compiles


> D does not have anonymous enums. Either you're declaring an enum which creates a new type and therefore has a name and a base type, or you're just creating manifest constants that don't create a new type. e.g.
>
> enum MyEnum : string
> {
>     a = "hello",
>     b = "foo",
>     c = "dog",
>     d = "cat"
> }
>
> vs
>
> enum string a = "hello";
> enum string b = "foo";
> enum string c = "dog";
> enum string d = "cat";
>
> or
>
> enum a = "hello";
> enum b = "foo";
> enum c = "dog";
> enum d = "cat";
>
> If you want a function to accept values that aren't tied to a specific enum, then just have the function take the base type.
>
> Now, within sections of code, you can use the with statement to reduce how often you have to use the enum type's name, e.g.
>
> with(MyEnum) switch(enumVal)
> {
>     case a: { .. }
>     case b: { .. }
>     case c: { .. }
>     case d: { .. }
> }
>
> but you can't have an enum without a name or just choose not to use an enum's name. With how enums work in D, there's really no point in having them if you're not going to treat them as their own type or refer to them via the enum type's name. If that's what you want to do, then just create a bunch of manifest constants.
>
> - Jonathan M Davis


December 17, 2017
On 2017-12-17 12:49, kerdemdemir wrote:
> I have an enum statement :
> 
> enum : string
> {
>      KErdem
>      Ali
>      Zafer
>      Salih
>      //etc...
> }
> 
> 
> I don't want to give a name to my enum class since I am accessing this variables very often.
> 
> But I also have a function like:
> 
> double ReturnCoolNess( /* Is there any way? */ enumVal )
> {
>    switch (enumVal)
>    {
>      case KErdem:
>      {
>          return 0.0
>      }
>      case Ali:
>      {
>          return 100.0;
>      }
>      case Salih:
>      {
>          return 100.0;
>      }
>          // etc..
>    }
> }
> 
> Is there any way I still keep my enum anonymous and be able to call functions with different enumarations. Or is there any other way to call named enums without type name ?

You have three options:

* Specify "string" as the type of the parameter for the ReturnCoolNess function. Note that this will allow any string to be passed to this function

* Use the "with" statement to avoid having to specify the enum name. This needs to be used in every place you want to access the enum members

enum Foo : string
{
    KErdem
    Ali
    Zafer
    Salih
    //etc...
}

double ReturnCoolNess(Foo enumVal )
{
    with(Foo)
        switch (enumVal)
        {
            case KErdem:
            {
                return 0.0
            }
            case Ali:
            {
                return 100.0;
            }
            case Salih:
            {
                return 100.0;
            }
            // etc..
        }
}

* Use "alias" to make the enum members available without having to specify the enum name:

enum Foo : string
{
    KErdem
    Ali
    Zafer
    Salih
    //etc...
}

alias KErdem = Foo.KErdem
alias Ali = Foo.Ali
// etc...

Now you can access the enum members through the aliases. Specify "Foo" as the type of the parameter in the ReturnCoolNess function. Generating these alias can be automated with some metaprogramming and string mixins.

-- 
/Jacob Carlborg
December 17, 2017
On Sunday, December 17, 2017 12:47:26 kerdemdemir via Digitalmars-d-learn wrote:
> What I meant with anonymous enums was: https://dlang.org/spec/enum.html#anonymous_enums. Maybe I couldn't explain well but I believe D have anonymous enums. I am sorry I have forgotten to remove " :string" in my example from the "enum : string". Please stretch out ": string" part my problem is not related with that.

That's pretty much just declaring manifest constants with braces so that you don't repeat the keyword enum a bunch of times.

enum
{
    a = "foo",
    b = "bar",
    c = "baz";
}

is identical to

enum a = "foo";
enum b = "bar";
enum c = "baz";

and it will even let you mix types, e.g.

enum
{
    a = "foo",
    b = 42
}

which you can't do with actual enums. You're not declaring a new type. You're just declaring a bunch of constants. They're really not enums in the classic sense, and for the most part, folks around here aren't going to call them enums. If anything, a number of folks complain that the keyword enum was reused for manifest constants. I don't know why the documentation has a section for "anonymous enums" separate from manifest constants, since they're really not a different thing, and AFAIK, pretty much no one calls them that - though at least they're right next to the documentation for manifest constants.

- Jonathan M Davis

December 18, 2017
On 2017-12-17 20:45, Jonathan M Davis wrote:

> That's pretty much just declaring manifest constants with braces so that you
> don't repeat the keyword enum a bunch of times.

Anonymous enum is what the spec calls it and was available before manifest constants.

-- 
/Jacob Carlborg
December 20, 2017
> enum
> {
>     a = "foo",
>     b = "bar",
>     c = "baz";
> }
>
> is identical to
>
> enum a = "foo";
> enum b = "bar";
> enum c = "baz";
>

Thanks Jonathan I think that changes my point of perspective.

And Jacob Carlborg I like the third option a lot with aliases good to know that

enum Foo : string
{
    KErdem
    Ali
    Zafer
    Salih
    //etc...
}

alias KErdem = Foo.KErdem
alias Ali = Foo.Ali
// etc...

Erdem