C++ Logo

std-proposals

Advanced search

Re: [std-proposals] std::elide

From: Tiago Freire <tmiguelf_at_[hidden]>
Date: Tue, 4 Jun 2024 15:09:02 +0000
Here’s an example of a class that needs fixing:

class object_token
{
public:
      template<typename T>
      explicit object_token(T const& p_object)
            : m_intenal_type{typeid(T)}
            , m_user_token{reinterpret_cast<void const*>(&p_object)}
      {
      }

      void const* token() const { return m_user_token; }
      std::type_info const& info() const { return m_intenal_type; }
private:
      std::type_info const& m_intenal_type;
      void const* m_user_token = nullptr;
};

How would I fix that?
Notice class is not templated, no CTAD required.


From: Robert A.H. Leahy <rleahy_at_[hidden]>
Sent: Tuesday, June 4, 2024 16:49
To: Tiago Freire <tmiguelf_at_[hidden]>; std-proposals_at_[hidden]
Subject: Re: [std-proposals] std::elide

template<typename T>
struct foo {
  template<typename... Args>
    requires std::constructible_from<T, Args...>
  explicit foo(Args&&... args) : t_(std::forward<Args>(args)...) {}
private:
  T t_;
};

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

--Robert

________________________________
From: Tiago Freire <tmiguelf_at_[hidden]<mailto:tmiguelf_at_[hidden]>>
Sent: Tuesday, June 4, 2024 10:45
To: Robert A.H. Leahy <rleahy_at_rleahy.ca<mailto:rleahy_at_[hidden]>>; std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]> <std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]>>
Subject: RE: [std-proposals] std::elide


Ok, and how would you do that? for reference….





From: Robert A.H. Leahy <rleahy_at_[hidden]<mailto:rleahy_at_[hidden]>>
Sent: Tuesday, June 4, 2024 16:14
To: Tiago Freire <tmiguelf_at_[hidden]<mailto:tmiguelf_at_[hidden]>>; std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]>
Subject: Re: [std-proposals] std::elide



That's also not a problem.



Constrain your templated constructors properly, if you don't that's a design problem, not a problem with the language standard.



Thanks,



--Robert

________________________________

From: Tiago Freire <tmiguelf_at_[hidden]<mailto:tmiguelf_at_[hidden]>>
Sent: Tuesday, June 4, 2024 10:12
To: std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]> <std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]>>
Cc: Robert A.H. Leahy <rleahy_at_[hidden]<mailto:rleahy_at_[hidden]>>
Subject: RE: [std-proposals] std::elide



I think you misunderstand the problem.

The problem was with templated constructors of a class, not with the constructor of a templated class.



From: Std-Proposals <std-proposals-bounces_at_[hidden]<mailto:std-proposals-bounces_at_[hidden]>> On Behalf Of Robert A.H. Leahy via Std-Proposals
Sent: Tuesday, June 4, 2024 16:03
To: std-proposals_at_lists.isocpp.org<mailto:std-proposals_at_[hidden]>
Cc: Robert A.H. Leahy <rleahy_at_[hidden]<mailto:rleahy_at_[hidden]>>
Subject: Re: [std-proposals] std::elide



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]<mailto:std-proposals-bounces_at_[hidden]>> on behalf of Frederick Virchanza Gotham via Std-Proposals <std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]>>
Sent: Tuesday, June 4, 2024 03:41
To: std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]> <std-proposals_at_[hidden]<mailto:std-proposals_at_[hidden]>>
Cc: Frederick Virchanza Gotham <cauldwell.thomas_at_[hidden]<mailto: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]<mailto:Std-Proposals_at_[hidden]>
https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals

Received on 2024-06-04 15:09:08