Storing a range as a data member

Storing a range instance in a non-template class or struct can be difficult because the type isn't always obvious and is sometimes completely unavailable. Ranges are typically for temporary use, and thus they don't need to be stored for long and are usually eligible for auto type deduction, but if you do need to store it, there are two options.

How to do it…

We can store a range as a data member by executing the following steps:

  1. The first option is to use one of the object-oriented wrappers as follows:
    import std.range;
    InputRange!int rangeObj;
    rangeObj = inputRangeObject(your_range);

    Remember, there is a performance penalty for this method, but it does have the advantage of being reassignable by different types of ranges as needed.

  2. Alternatively, we can use the typeof operator to get the range type out of the function, as shown in the following code:
    typeof(function_that_returns_a_range) rangeObj;

The code is as follows:

import std.algorithm;
typeof(filter!((a) > 0)([1,2,3])) filteredRange; // declare it
this() {
    filteredRange = filter!((a) > 0)([1, 2, 3]); // initialize it
}

How it works…

The typeof operator can be used anywhere in D where you need a type. When passed a variable or expression, it returns the static (compile-time) type of that variable or expression. When passed a function call, it returns the return type of the function. This can be used as a tool in compile-time reflection, for convenience with complex types, or generic code.

The typeof operator works even when the type is not otherwise available, such as a struct in a module you haven't imported, or if the type has no name. In Phobos, many range functions return nested structs, as shown in the following code:

auto hiddenType() {
   struct Foo { }
   return Foo();
}
auto test = hiddenType(); /* test has a type whose definition is not available outside the hiddenType function. Calling it Foo or hiddenType.Foo will not work because types declared inside functions are not available outside. */

This is sometimes called a Voldemort type, referencing a fictional character whose name is not allowed to be spoken.

When using auto type deduction, everything just works; however, if you need to declare a variable of that type before it is used, this presents a problem. The typeof operator is a solution, as shown:

typeof(hiddenType()) test = hiddenType(); // works!

As ranges often have complex or hidden type names, typeof may be the only way to refer to them without an auto type deduced variable.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.147.72.74