C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::elide

From: Robert A.H. Leahy <rleahy_at_[hidden]>
Date: Tue, 4 Jun 2024 14:03:17 +0000
If class authors don't want their class template arguments to be deduced from a std::elide they can implement that using template metaprogramming:

template<typename T>
struct deduce : std::remove_cvref<T> {};

namespace detail::deduce {

template<typename>
struct extract;
template<typename T>
struct extract<elide<T>> : std::type_identity<T> {};

}

template<typename T>
  requires requires {
    typename detail::deduce::extract<std::remove_cvref_t<T>>::type;
  }
struct deduce<T> : std::type_identity<
  decltype(std::forward_like<T>(std::declval<
    typename detail::deduce::extract<std::remove_cvref_t<T>>::type>())())> {};

template<typename T>
using deduce_t = typename deduce<T>::type;

And then simply write a deduction guide:

template<typename T>
explicit my_class(T&&) -> my_class<deduce_t<T>>;

There's no need to make the assumption that no one ever wants a class template argument deduced from an elide (probably wrong) and then reify that in the core language.

Thanks,

--Robert
________________________________
From: Std-Proposals <std-proposals-bounces_at_[hidden]> on behalf of Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]>
Sent: Tuesday, June 4, 2024 03:41
To: std-proposals_at_[hidden] <std-proposals_at_lists.isocpp.org>
Cc: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]>
Subject: Re: [std-proposals] std::elide

On Tue, Jun 4, 2024 at 3:54 AM Robert A.H. Leahy wrote:
>
> I don't understand why we need to prevent std::elide from
> becoming a constructor argument. In fact I have use cases
> exactly where I want std::elide (or its equivalent) to be an
> argument to a constructor with a single argument.


I was able to find a use case for when I wanted an std::elide to be a
constructor parameter, but not when there is only one parameter.


> What we want, if anything, is a way to prevent std::elide
> from being deduced from a constructor call as a class
> template argument via CTAD, but there are library solutions
> to that problem.


I'm just realising now that this might be the real problem. Maybe the
change to the core language needs to be for the programmer to have the
ability to tell the compiler that their class should never be deduced
as a template argument for a constructor. So the following should
succeed:

    template<typename T> class MyClass {};
    int main(void)
    {
        MyClass< elide<mutex> > var( some_elider_variable );
    }

but the following should fail:

    template<typename T> class MyClass {};
    int main(void)
    {
        MyClass var( some_elider_variable );
    }

So perhaps we could mark a class to ensure this failure:

    class elide fail_ctad_single_param_constructor {
    };

Writing "fail_ctad_single_param_constructor" after a class name
ensures two things:
    (1) The class won't be deduced as the template argument to another
class's single-argument constructor
    (2) The class however can be explicitly specified as a template
argument to another class's single-argument constructor

So now there are four options to choose from:

------ Option No. 1: Don't prevent the template instantiation at all.

------ Option No. 2: Prevent the template instantiation by
appending a paragraph to 13.10.3.1.11 (as is currently suggested in
the paper).

------ Option No. 3: Prevent the template instantiation by marking
the conversion operator as 'priority'

    template<typename T>
    class elide {
        operator T() priority
        {
        }
    };

------ Option No. 4: Prevent the template instantiation by marking
the class as 'no_ctad_single_param_constructor'.

    template<typename T>
    class elide fail_ctad_single_param_constructor {
        operator T()
        {
        }
    };
--
Std-Proposals mailing list
Std-Proposals_at_[hidden]
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2024-06-04 14:03:21