Date: Fri, 31 May 2024 11:33:34 +0100
On Fri, May 31, 2024 at 10:10 AM Matthew Taylor wrote:
>
> > Did anyone like my previous idea of having a way of
> > telling the compiler that we want template instantiation to fail?
>
> At the risk of stating the obvious, the difficulty there is that such
> an idea is a sledgehammer which could be a major change to
> template programming; and such an idea needs serious, strong
> motivation which goes far beyond being a workaround to make
> a different proposed feature's edge cases work. Particularly as
> at least a few of the potential use-cases for it can already be
> achieved in the language as it is now.
Well . . . while we're sharing revolutionary ideas for the upheaval of
the language . . . (Bjarne did it so I can too) . . .
Let's look at what the real problem is here. The following fails to compile:
optional<mutex> om;
om.emplace( FuncReturnsMutexByValue(1,2,some_global_variable) );
It fails to compile because "FuncReturnsMutexByValue()" is a PRvalue,
and the 'emplace' method won't accept a PRvalue. But let's say that
the C++ programming language were to be augmented in C++26 to allow us
to write a function that accepts a PRvalue as an argument as follows:
template<typename T>
T &emplace(T ^^arg);
which for our above variable whose type is "std::optional<mutex>" becomes:
mutex &emplace(mutex ^^arg);
So now when the compiler encounters the following line:
om.emplace( FuncReturnsMutexByValue(1,2,some_global_variable) );
It does the following:
Step 1 - Determine that the argument to 'emplace' is a PRvalue mutex
Step 2 - Check whether "optional<mutex>::emplace" has an overload
that takes a PRvalue mutex
Step 3 - Immediately evaluate the arguments which are passed to
"FuncReturnsMutexByValue", however delay the invocation of
"FuncReturnsMutexByValue" until the 'emplace' method explicitly
invokes it.
And so then the implementation of
"std::optional<mutex>::emplace(mutex^^)" would be as follows:
mutex &emplace(mutex ^^arg)
{
this->reset();
T &retval = ::new(this->buffer) mutex( arg() );
this->has_value_bool = true;
return retval;
}
And so as you can see in the above snippet, the argument 'arg' is a
functor object which invokes "FuncReturnsMutexByValue" with the
arguments "1, 2, some_global_variable". As I mentioned earlier, the
evaluation of the arguments "1, 2, global_variable" happens before the
'emplace' method is invoked.
So there you have it people -- C++26 needs to have functions that
accept PRvalues as parameter types.
>
> > Did anyone like my previous idea of having a way of
> > telling the compiler that we want template instantiation to fail?
>
> At the risk of stating the obvious, the difficulty there is that such
> an idea is a sledgehammer which could be a major change to
> template programming; and such an idea needs serious, strong
> motivation which goes far beyond being a workaround to make
> a different proposed feature's edge cases work. Particularly as
> at least a few of the potential use-cases for it can already be
> achieved in the language as it is now.
Well . . . while we're sharing revolutionary ideas for the upheaval of
the language . . . (Bjarne did it so I can too) . . .
Let's look at what the real problem is here. The following fails to compile:
optional<mutex> om;
om.emplace( FuncReturnsMutexByValue(1,2,some_global_variable) );
It fails to compile because "FuncReturnsMutexByValue()" is a PRvalue,
and the 'emplace' method won't accept a PRvalue. But let's say that
the C++ programming language were to be augmented in C++26 to allow us
to write a function that accepts a PRvalue as an argument as follows:
template<typename T>
T &emplace(T ^^arg);
which for our above variable whose type is "std::optional<mutex>" becomes:
mutex &emplace(mutex ^^arg);
So now when the compiler encounters the following line:
om.emplace( FuncReturnsMutexByValue(1,2,some_global_variable) );
It does the following:
Step 1 - Determine that the argument to 'emplace' is a PRvalue mutex
Step 2 - Check whether "optional<mutex>::emplace" has an overload
that takes a PRvalue mutex
Step 3 - Immediately evaluate the arguments which are passed to
"FuncReturnsMutexByValue", however delay the invocation of
"FuncReturnsMutexByValue" until the 'emplace' method explicitly
invokes it.
And so then the implementation of
"std::optional<mutex>::emplace(mutex^^)" would be as follows:
mutex &emplace(mutex ^^arg)
{
this->reset();
T &retval = ::new(this->buffer) mutex( arg() );
this->has_value_bool = true;
return retval;
}
And so as you can see in the above snippet, the argument 'arg' is a
functor object which invokes "FuncReturnsMutexByValue" with the
arguments "1, 2, some_global_variable". As I mentioned earlier, the
evaluation of the arguments "1, 2, global_variable" happens before the
'emplace' method is invoked.
So there you have it people -- C++26 needs to have functions that
accept PRvalues as parameter types.
Received on 2024-05-31 10:33:47