Thread overview
Template alias parameter: error: need 'this' for ...
Feb 24, 2023
Elfstone
Feb 24, 2023
user1234
Feb 24, 2023
Paul Backus
Feb 25, 2023
Elfstone
February 24, 2023
https://forum.dlang.org/post/imnannjdgtjnlzevhwez@forum.dlang.org

On Saturday, 24 August 2013 at 11:47:43 UTC, Matej Nanut wrote:
> On Friday, 23 August 2013 at 22:54:33 UTC, Jonathan M Davis wrote:
>> Because without static it's a member variable, which means that you have to
>> have a constructed object to access it (since it's part of the object). When
>> you declare a variable in a class or struct static, then there's only one for
>> the entire class or struct, so it can be accessed without an object. And when
>> you do StructName.var or ClassName.var your accessing the variable via the
>> struct or class rather than an object, so the variable must be static.
>>
>> - Jonathan M Davis
>
> But I declared the template static, not the variable.
>
> Is there a better way to pass a ‘member get’ expression to a template?
>
> I need this for calling ‘.offsetof’ on it, and for checking if the member's parent is a certain struct type.

Seems like the same bug is still there after ten years.


	struct Bar
	{
		@("hello") int t;
	}

	static bool hasAttribute(alias F, T)()
	{
		bool result = false;
		foreach (a; __traits(getAttributes, F))
		{
			static if (is(typeof(a) : T))
			{
				result = true; // couldn't simply return true, 'cause the compiler complains about "unreachable code".
			}
		}
		return result;
	}

	void main()
	{
		import std.stdio;

		writeln(hasAttribute!(Bar.t, string));
	}
February 24, 2023

On Friday, 24 February 2023 at 12:00:41 UTC, Elfstone wrote:

>

Seems like the same bug is still there after ten years.

	struct Bar
	{
		@("hello") int t;
	}

	static bool hasAttribute(alias F, T)()
	{
		bool result = false;
		foreach (a; __traits(getAttributes, F))
		{
			static if (is(typeof(a) : T))
			{
				result = true; // couldn't simply return true, 'cause the compiler complains about "unreachable code".
			}
		}
		return result;
	}

	void main()
	{
		import std.stdio;

		writeln(hasAttribute!(Bar.t, string));
	}

you can break using goto, restore static everywhere, and using local introspection determine whether the result exists.

struct Bar
{
	@("hello") int t;
}

static bool hasAttribute(alias F, T)()
{
	static foreach (a; __traits(getAttributes, F))
	{
		static if (is(typeof(a) : T))
		{
			enum result = true;
			goto L0;
		}
	}
	L0:
	static if (is(typeof(result)))
		return result;
	else
		return false;
}

void main()
{
	import std.stdio;

	writeln(hasAttribute!(Bar.t, string));
}
February 24, 2023

On 2/24/23 7:00 AM, Elfstone wrote:

>

Seems like the same bug is still there after ten years.

static should not affect module-level functions, but also, this code should work without static.

Reported, not sure if there's a previous bug, it was hard to come up with a good description:

https://issues.dlang.org/show_bug.cgi?id=23738

-Steve

February 24, 2023

On Friday, 24 February 2023 at 14:22:17 UTC, user1234 wrote:

>

you can break using goto, restore static everywhere, and using local introspection determine whether the result exists.

struct Bar
{
	@("hello") int t;
}

static bool hasAttribute(alias F, T)()
{
	static foreach (a; __traits(getAttributes, F))
	{
		static if (is(typeof(a) : T))
		{
			enum result = true;
			goto L0;
		}
	}
	L0:
	static if (is(typeof(result)))
		return result;
	else
		return false;
}

void main()
{
	import std.stdio;

	writeln(hasAttribute!(Bar.t, string));
}

Unfortunately there is a serious bug in this code. Take a look at what happens when you try it with this struct Bar:

struct Bar
{
	@("hello") @("goodbye") int t;
}
February 25, 2023

On Friday, 24 February 2023 at 15:28:18 UTC, Steven Schveighoffer wrote:

>

On 2/24/23 7:00 AM, Elfstone wrote:

>

Seems like the same bug is still there after ten years.

static should not affect module-level functions, but also, this code should work without static.

Reported, not sure if there's a previous bug, it was hard to come up with a good description:

https://issues.dlang.org/show_bug.cgi?id=23738

-Steve

It was marked duplicate. I read the comments to the previous issue and felt like reading C++ discussions, except C++ is a lot better documented.

Anyway surely __traits(getAttributes, Bar.t) compiles. The compiler should "need 'this'" when it actually need 'this' - unless there are attributes that can be bound to 'this'.