Date: Fri, 31 May 2024 09:08:48 +0100
On Thu, May 30, 2024 at 4:35 PM Arthur O'Dwyer wrote:
>
> constexpr R operator()() noexcept( <snip> )
> {
> return *this;
> }
Okay I think I understand now. So "std::elide" could be given a
functor operator as follows:
constexpr R operator()(void) noexcept(noexcept(this->operator R()))
{
return this->operator R();
}
And then we could write a separate elider class as follows:
template<typename R> requires (!std::is_reference_v<R>)
class MyElider {
std::function<R(void)> stdf;
public:
template<typename F, typename... Params>
MyElider(F &&f, Params&&... args)
{
stdf = [ &f, &args... ](void) -> R
{
return std::forward<F>(f)( std::forward<Params>(args)... );
};
}
operator R(void) { return stdf(); }
R operator()(void) { return *this; }
};
And then we'd be able to chain them like:
ocs8.emplace( std::elide( MyElider(
std::elide(ReturnByValueWithArg,7) ) ) );
ocs8.emplace( MyElider( std::elide(
MyElider(ReturnByValueWithArg,8) ) ) );
Is that right?
There's a problem with this though, as follows:
(1) With the core language change, MyElider won't accept
'std::elide' as a constructor parameter
(2) Without the core language change, 'std::elide' won't work with
classes that have an accept-any-parameter constructor
Did anyone like my previous idea of having a way of telling the
compiler that we want template instantiation to fail? That is to say,
we give a "template instantiation failure guide" to the compiler? So
if we don't want 'std::elide' or 'MyElider' to ever be a constructor
parameter, we would tell the compiler:
false template<class C, typename T> requires
std::is_specialization_v< std::remove_cvref_t<T>, std::elide >
C::C(T&&);
And then if we want to override such a 'failure guide', we write "true
template" instead of "false template" after it as follows:
true template<typename T> requires std::is_specialization_v<
std::remove_cvref_t<T>, std::elide > MyElider::MyElider(T&&);
true template<typename T> requires std::is_specialization_v<
std::remove_cvref_t<T>, MyElider > std::elide::elide(T&&);
>
> constexpr R operator()() noexcept( <snip> )
> {
> return *this;
> }
Okay I think I understand now. So "std::elide" could be given a
functor operator as follows:
constexpr R operator()(void) noexcept(noexcept(this->operator R()))
{
return this->operator R();
}
And then we could write a separate elider class as follows:
template<typename R> requires (!std::is_reference_v<R>)
class MyElider {
std::function<R(void)> stdf;
public:
template<typename F, typename... Params>
MyElider(F &&f, Params&&... args)
{
stdf = [ &f, &args... ](void) -> R
{
return std::forward<F>(f)( std::forward<Params>(args)... );
};
}
operator R(void) { return stdf(); }
R operator()(void) { return *this; }
};
And then we'd be able to chain them like:
ocs8.emplace( std::elide( MyElider(
std::elide(ReturnByValueWithArg,7) ) ) );
ocs8.emplace( MyElider( std::elide(
MyElider(ReturnByValueWithArg,8) ) ) );
Is that right?
There's a problem with this though, as follows:
(1) With the core language change, MyElider won't accept
'std::elide' as a constructor parameter
(2) Without the core language change, 'std::elide' won't work with
classes that have an accept-any-parameter constructor
Did anyone like my previous idea of having a way of telling the
compiler that we want template instantiation to fail? That is to say,
we give a "template instantiation failure guide" to the compiler? So
if we don't want 'std::elide' or 'MyElider' to ever be a constructor
parameter, we would tell the compiler:
false template<class C, typename T> requires
std::is_specialization_v< std::remove_cvref_t<T>, std::elide >
C::C(T&&);
And then if we want to override such a 'failure guide', we write "true
template" instead of "false template" after it as follows:
true template<typename T> requires std::is_specialization_v<
std::remove_cvref_t<T>, std::elide > MyElider::MyElider(T&&);
true template<typename T> requires std::is_specialization_v<
std::remove_cvref_t<T>, MyElider > std::elide::elide(T&&);
Received on 2024-05-31 08:09:01