difficulties with const structs and alias this / template functions

Stanislav Blinov stanislav.blinov at gmail.com
Sun Nov 18 18:17:54 UTC 2018


On Sunday, 18 November 2018 at 17:30:18 UTC, Dennis wrote:
> I'm making a fixed point numeric type and want it to work 
> correctly with const. First problem:
>
> ```
> const q16 a = 6;
> a /= 2;          // compiles! despite `a` being const.

Ouch. That's actually kind of nasty.

> writeln(a);      // still 6
> a.toQ32 /= 2;    // what's actually happening
> ```
>
> My q16 type has an implicit conversion to q32 (like how int can 
> be converted to long):
> ```
> q32 toQ32() const {
>   return q32(...);
> }
> alias toQ32 this;
> ```
> How do I make it so that a const(q16) will be converted to a 
> const(q32) instead of mutable q32?

Like this:

         // implement separate methods for mutable/const/immutable
         q32 toQ32() {
             return q32(x);
         }

         const(q32) toQ32() const {
             return q32(x);
         }

         immutable(q32) toQ32() immutable {
             return q32(x);
         }

Or like this:

         // implement all three in one method, using the `this 
template` feature
         auto toQ32(this T)() {
             static if (is(T == immutable))
                 return immutable(q32)(x);
             else static if (is(T == const))
                 return const(q32)(x);
             else
                 return q32(x);
         }


> Second problem:
> ```
> Q log2(Q)(Q num) if (is(Q : q16) || is(Q : q32)) {
>     import std.traits: Unqual;
>     Unqual!Q x = num;
>     // actual code
> }
> ```
> When I call this with a const(q16), Q is resolved to const(q16) 
> so I have to unqualify Q every time. It works, but feels 
> clumsy. Is there an easier way to automatically de-const 
> parameters? We're working with small value types here, it 
> should be simple.

Define different overloads for Q and const Q. Or this:

Q log2(Q)(inout Q num) if (is(Q : q16) || is(Q : q32)) { /* ... 
*/ }

Being able to jam mutable/const/immutable implementation in one 
function like that should tell you that you shouldn't mutate the 
argument. Then, the necessity to Unqual will go away on it's own 
;)


More information about the Digitalmars-d-learn mailing list