D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 5040 - opOpAssign should be automatically visible for types.
Summary: opOpAssign should be automatically visible for types.
Status: RESOLVED WONTFIX
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: All All
: P2 enhancement
Assignee: No Owner
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-10-11 05:56 UTC by Austin Hastings
Modified: 2022-11-29 09:38 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Austin Hastings 2010-10-11 05:56:53 UTC
This code:
==========
module scratch;

class S( T ) {
	T contents;
	
	T opIndexOpAssign( string op )( T value, int index ) {
		return contents.opOpAssign!op( value );
	}
}

unittest {
	auto s = new S!bool();
	
	s[ 1 ] |= true;
}
==========
Produces these diagnostics:
==========
$ dmd -c -unittest  scratch.d
scratch.d(7): Error: no property 'opOpAssign' for type 'bool'
scratch.d(7): Error: no property 'opOpAssign' for type 'bool'
scratch.d(7): Error: __error isn't a template
scratch.d(14): Error: template instance scratch.S!(bool).S.opIndexOpAssign!("|") error instantiating
==========

Defining the various binary ops as templates is a good idea, because it makes them manageable as a group. But the whole family of indexOpAssign, indexAssign, OpAssign, and assign functions will frequently wind up as a nest of snakes.
 
Being able to define some of these functions in terms of other functions is a valuable feature. Presently, as in the example above, an attempt to reference the template version of the |= operator produces an error.

For built-in types, and possibly others, it should be possible to use the template op*!string syntax to generically invoke an operator, rather than making an explicit template for |=, where the generic invocation will be converted into an operator, which will be converted back into the generic invocation behind the scenes...
Comment 1 Maksim Zholudev 2016-03-28 13:16:32 UTC
The same can be done with string mixin:
--------------------
T opIndexOpAssign(string op)(T value, int index)
{
    return mixin("contents " ~ op ~ "= value");
}
--------------------

Anyway, the possibility to call operator as function (regardless whether it is defined explicitly or not) for both built-in and user-defined types could make this part of D more consistent.
Comment 2 RazvanN 2022-11-29 09:38:08 UTC
The operators may only be defined for classes and structs. For generic code, the mixin construct may be used as previously stated. In D there is a distinction between basic types and aggregate types and not all aggregate operators make sense in the context of builtin types. Also, adding the extra complexity in the compiler does not worth it, considering that we have a perfectly valid workaround.