On Thursday, 25 July 2024 at 13:07:03 UTC, Jonathan M Davis wrote:
On Thursday, July 25, 2024 6:00:58 AM MDT Dom DiSc via
But a parameter given by value is ALWAYS a copy.

It has to be a _full_, independent copy. If you're talking about integer types, that's a non-issue, but if you're talking about types with any indirections, it becomes a big issue. If the type contains any pointers, dynamic arrays, class references, etc. then the copy can't be mutable unless you're dealing with a struct with a copy constructor that does a deep copy of all of the member variables. So, in the general case, you cannot copy a value and expect to get a mutable result.

If you are not able to construct a mutable copy of a type, why on earth are you handing it over by value?!?

And what do you do with normal assignment with such a type?

```d
immutable MyNonCopyableType x;
MyNonCopyableType y = x; // compile error?
```

Also, if you need no writeable copy in your template, why don't you declare it with const parameter? Maybe you need this behaviour often and so don't want to type the 7 extra characters. But I think, it is a bad default to create const copies of const objects, and to make it worse the language does not allow you to change this default (would need a new keyword "mutable" to explicitly request to get a mutable copy).

Therefore I consider the current behaviour a bug.

It's most definitely not a bug that IFTI (Implicit Function Template Instantiation) instantiates the template with the exact type that it's given. In the general case, that's what you want - particularly since many, many types (probably the vast majority of types) cannot be const or immutable and then result in a mutable copy when they're copied.

If you need this, declare the parameter const.
The default should be a mutable copy (and a compile error if creating a mutable copy is not possible).

That really only works with very simple types with no indirections.

Sorry, but no. It is possible to write copy constructors that create mutable copies for pretty much any type. It may for bad designed types be not very fast, but if you are able to create a mutable instance of a type, it should also be possible to create a mutable copy.


Now, the fact that code such as
    ```
    void fun(T : const U, U)(U x)
        if(is(immutable T == immutable U))
    {
        ...
    }
    ```
or code like
    ```
    void fun(T)(Unqual!T x) {}
    ```
doesn't work with IFTI and requires explicit instantation is definitely a deficiency in IFTI's current capabilities.

So you basically agree that it is a missing feature (if not a bug).

we very much want
    ```
    void fun(T)(T x) {}
    ```
to be instantiated as fun!(const Foo) if it's passed a const Foo.

No. this is a bad default. If you want this, write

```d
void fun(T)(const(T) x) {}
```

I know, it's seven characters more to type, but I think they are definitely worth it.

Reply via email to