Date: Sun, 12 Apr 2026 15:05:16 +0500
In my previous email when I said that "references are not possible as a way
to provide specialization", I was wrong, like You can in fact do so:
template<typename T...>
struct variant;
template<typename T...>
struct variant<T&...>{
}
I am really really sorry for my mistake!!!!! I didn't think it through and
didn't test it using code as well.
On Sun, Apr 12, 2026 at 2:59 PM Muneem <itfllow123_at_[hidden]> wrote:
> ***question:***: how do you provide a class specialization specifically
> for reference T, without breaking the rule that a name used by a class cant
> be used for anything else in the same namespace/class/function scope.
> > No, actually this would change the current workings of std::optional.
> Currently, it throws if you call value() on it. Instead, we can also check
> if there is a valid option and then use operator* (which is UB to use if it
> doesn’t contain a value). The advantage of this approach is, that you do
> not force anybody to use exceptions. Some people really don’t like them.
> There is also no harm in constructing an empty optional when it is never
> used.
> **** Response ***:You have a point!
> >Usually, if the template parameter is a T& we would implement it as a
> pointer internally (just like you did). To the compiler, references and
> pointers look the same anyway (it’s just that you cannot reassign a
> reference to point to anything else). I think that this point is mostly
> solved already. As I said, I’m not sure about the status of the proposal
> for std::optional<T&>. But, exactly the same discussions would apply to
> std::variant<T&…>.
> **** Response ***: it's not problem solved if you allow references to be
> in tagged unions like std::variant because references are by nature have
> all their information known at compile time since its like a reference to
> an variable, making them be in unions requires you to implement some sort
> of support under the hood. There is a reason why references are only
> allowed in structs, not in anything that is "union like", since such
> support requires underlying pointers. Basically, it would be like
> variant<T* const....> except that it would have a specific new
> specialization that nothing depends on: std::variant<T..., reference_tag>
> and it can't hold nullptrpointers?
> >There is no branching needed. There are always two ways to specify
> conversion: one would be to write an std::variant::operator=. However, we
> would need to specify the desired type of the optional as a template
> parameter. The easier solution would be:
> template <Args&…>
> std::optional<T&>::optional(std::variant<Args…> &variant)
> : m_storage(std::holds_alternative<T&>(variant) ?
> std::get<T&>(variant) : std::nullopt)
> {}
> ****Response***: 1. std::variant::operator= would still need branching
> just like variants already have but would also need special support for
> having references in "tagged unions" , and 2. holds_alternative<> cant be
> passed references so again you do need some specialization of
> hold_alternative, and again, how do you do that!?
>
> A full proposal for this extension needs to discuss/consider a few things:
> 1. What kind of overloads do we need (const/non-const, &/&&)
> 2. Additional modifiers like constexpr and noexcept
> 3. Do we only propose this conversion just for std::optional<T&> or also
> for std::optional<T>
> 4. What should happen if there are duplicate types inside the variant
> (never happens with your use case)
> 5. Note that this does not compile if the type T& of the optional is not
> one of the types of the variant
> ****RESPONSE****: How about I say:
> 1. We can provide overloads for tuple<T..., Runtime_index_tag> and
> variant<T..., reference_tag>, like you cant I dont think I dont think you
> can just provide a
> std::variant<T...> without breaking the rule that a name used by a class
> cant be used for anything else in the same namespace/class/function scope.
> 2. subscripting operations and constructor for the tuple<T...,
> Runtime_index_tag> would be constexpr, with optimizations for the runtime
> execution be provided through a branch set by "std::is_constant_evaluated".
> For std::optional<T> , we need the same, that is a constexpr
> constructor/assignment function that checks whether the variant has the
> correct type or does it have any at all and throws a compiler error, while
> a runtime version throws an error. This would of course require a
> std::variant member consteval function "is compile time constructed" used
> by that branch(the one branched by is_constant_evaluated), and a
> std::variant constexpr constructor that sets the value returned by that to
> true in its own "is_constant_evaluated==true" branch, but by default that
> underlying value would be false. This provides a full set of optimizations
> if any index into the tuple is constexpr.
> 3,. I would say provide for both std::optional<T> and std::optional<T> so
> as to support some way of moving/copying the value of the variant.
> 4. tuple<T..., Runtime_index_tag> would have to return
> std::variant<enable_if<std::is_same_v< Is_t_in_set <T, T...>, t true_t
> >>...> as the return type of indexing, where in_t_in_set would obviously be
> classic bjarne stourstrup style stuff:
>
> struct false_t {};
>
> struct true_t {};
>
> template<typename T, typename... Tail>
>
> struct Is_t_in_set;
>
> template<typename T, typename Head_t, typename... Tail>
>
> struct Is_t_in_set<T, Head_t, Tail...> {
>
> using boolean = std::conditional_t<
>
> std::is_same_v<T, Head_t>,
>
> true_t,
>
> typename Is_t_in_set<T, Tail...>::boolean
>
> >;
>
> };
>
> template<typename T, typename Head_t>
>
> struct Is_t_in_set<T, Head_t> {
>
> using boolean = std::conditional_t<
>
> std::is_same_v<T, Head_t>,
>
> true_t,
>
> false_t
>
> >;
>
> };
> credits to him of course for such confusing(yet effective) techniques.
> 5. yeah, exactly, it should not compile if: type T passed to (as a
> template arg) optional is not one of the types of the variant and to
> enforce this, you could ofcourse use SFINAE:
> template<typename T_of_optional>
> struct optional< T_of_optional , reference_tag >{
> //like optional<T&> but it is possible to exist thanks to the extra
> reference_tag overload tag
> typename<typename T..., template <typename T..., typename Tag> Variant_t>
> enable_if<std::is_same_v< Is_t_in_set < T_of_optional , T...>, t true_t
> > && std::is_same_v<T, reference_tag >>optional( Variant_t <T...,
> reference_tag > ){
> //now copy
>
> }
> }
> again the code is just pseudo code, like just to give you an idea of what
> I think, so the syntax maybe wrong
>
>
> >For proposing std::variant<Ts&…> we should also discuss if a std::variant
> should only be allowed to be either specified on only Ts… or Ts&…, or if we
> allow a mixture of Ts and T-refs. (Certainly, for what you want just Ts&…
> would suffice.) I’m not sure what the use case for a mixture would be, but
> I also don’t see the point in artificially restricting them.
> ***Answer***: let's keep the separate, like technically a class can't know
> for sure if some type can be reference or by value without a tag or
> without different class names. Its not mechanically possible in the current
> language facilities for variadic templates.
> >Concerning the immutability of the selected type of a variant this is
> just handled by making the variable of type std::variant const. There is no
> std::variant::operator=() const, so we cannot reassign to a const
> std::variant. Unfortunately, right now we also cannot reassign a value of
> the proper type to a const std::variant (that’s just a syntactical/optical
> deficiency).
> ***Answer***: so the overload for std::variant<T...,
> reference_tag>::operator=() const should simply move/copy into the
> underlying object pointed to by the reference?
>
> >One more thing for std::variant: I want to be able to convert a
> std::variant<int&,float&> to a std::variant<int,float> and also to an
> std::optional<int>. This way the user of the type can choose between
> getting a reference into the tuple or a copy of the value. (We need to
> discuss if it makes sense to move values outside the tuple; this would be a
> trap for UB.)
> ***ANSWER***: It won't be in the sense that if std::variant<int,float> is
> const then you can only copy/assign to the underlying object whose type is
> chosen during construction. For std::optional, its an exception if the user
> prefers to be safe, but if he uses unsafe (but faster) methods then yeah,
> undefined behaviour.
>
> >Extending std::tuple with operator[] also needs one discussion: Do we
> only allow this if all the types inside the tuple are distinct? I don’t see
> it necessary for proposing this extension. However, I’d want for the
> implementation of operator[] to make the types of the std::variant returned
> to be distinct even if the types of std::tuple are not.
> ***ANSWER***: It does require a discussion, but what do you mean by
> "distinct"? like in what way? is the variant gonna handle them differently?
>
> On Sun, Apr 12, 2026 at 11:59 AM Simon Schröder <
> dr.simon.schroeder_at_[hidden]> wrote:
>
>>
>>
>> On Apr 11, 2026, at 2:23 PM, Muneem via Std-Proposals <
>> std-proposals_at_[hidden]> wrote:
>>
>>
>> On 4/10/26 20:01, Simon Schröder via Std-Proposals wrote:
>> >std::optional<int&> x = list[0];
>> Just to make sure that we are on the same page:
>> we both agree that "std::optional<int&> x = list[index];"
>> 1. std::optional<int&> 's constructor should throw an exception if the
>> variant returned by list[index] is not an int.
>>
>> No, actually this would change the current workings of std::optional.
>> Currently, it throws if you call value() on it. Instead, we can also check
>> if there is a valid option and then use operator* (which is UB to use if it
>> doesn’t contain a value). The advantage of this approach is, that you do
>> not force anybody to use exceptions. Some people really don’t like them.
>> There is also no harm in constructing an empty optional when it is never
>> used.
>>
>> 2. For std::variant<T&...> to work, we need support from the
>> implementation just like the support I needed for type_set<T...>, this
>> support would be import such that we can avoid the T& to be changed, and
>> since unions cant have references, the implementation would need to come up
>> with some internal implementation.
>>
>> Usually, if the template parameter is a T& we would implement it as a
>> pointer internally (just like you did). To the compiler references and
>> pointers look the same anyway (it’s just that you cannot reassign a
>> reference to point to anything else). I think that this point is mostly
>> solved already. As I said, I’m not sure about the status of the proposal
>> for std::optional<T&>. But, exactly the same discussions would apply to
>> std::variant<T&…>.
>>
>>
>> Note: the branching that I talked about for "std::variant<T&...>
>> specialization to to some std::optional<T&> at runtime" in my email to
>> Mr.David Brown is the checking in point one.
>>
>> There is no branching needed. There is always two ways to specify
>> conversion: one would be to write an std::variant::operator=. However, we
>> would need to specify the desired type of the optional as a template
>> parameter. The easier solution would be:
>> template <Args&…>
>> std::optional<T&>::optional(std::variant<Args…> &variant)
>> : m_storage(std::holds_alternative<T&>(variant) ?
>> std::get<T&>(variant) : std::nullopt)
>> {}
>>
>> A full proposal for this extension needs to discuss/consider a few things:
>> 1. What kind of overloads do we need (const/non-const, &/&&)
>> 2. Additional modifiers like constexpr and noexcept
>> 3. Do we only propose this conversion just for std::optional<T&> or also
>> for std::optional<T>
>> 4. What should happen if there are duplicate types inside the variant
>> (never happens with your use case)
>> 5. Note that this does not compile if the type T& of the optional is not
>> one of the types of the variant
>>
>> For proposing std::variant<Ts&…> we should also discuss if a std::variant
>> should only be allowed to be either specified on only Ts… or Ts&…, or if we
>> allow a mixture of Ts and T-refs. (Certainly, for what you want just Ts&…
>> would suffice.) I’m not sure what the use case for a mixture would be, but
>> I also don’t see the point in artificially restricting them.
>>
>> Concerning the immutability of the selected type of a variant this is
>> just handled by making the variable of type std::variant const. There is no
>> std::variant::operator=() const, so we cannot reassign to a const
>> std::variant. Unfortunately, right now we also cannot reassign a value of
>> the proper type to a const std::variant (that’s just a syntactical/optical
>> deficiency).
>>
>> One more thing for std::variant: I want to be able to convert a
>> std::variant<int&,float&> to a std::variant<int,float> and also to an
>> std::optional<int>. This way the user of the type can choose between
>> getting a reference into the tuple or a copy of the value. (We need to
>> discuss if it makes sense to move values outside the tuple; this would be a
>> trap for UB.)
>>
>> Extending std::tuple with operator[] also needs one discussion: Do we
>> only allow this if all the types inside the tuple are distinct? I don’t see
>> it necessary for proposing this extension. However, I’d want for the
>> implementation of operator[] to make the types of the std::variant returned
>> to be distinct even if the types of std::tuple are not.
>>
>>
>> On 4/10/26 20:01, Bjorne Reese via Std-Proposals wrote:
>> >> 2. Add operator[] to std::tuple which returns const std::variant<Ts&…>
>>
>> >Better yet, a free function that works with any tuple-like object.
>>
>> 1. I can agree that it will be convenient, but I would also love to
>> emphasize that there should be a specific member function for the specific
>> tuple<T&...> meant for runtime that has its own different implementation.
>>
>>
>> @Bjorne: I do understand what you are saying here and why. I’m personally
>> a little annoyed by the syntax of std::get. In general, I prefer the member
>> access syntax (and we didn’t get automatic lookup of free-standing
>> functions for this so far). Especially with the use of runtime indices it
>> would be more consistent with arrays, vectors, etc. when using operator[]
>> (and I like it better). Certainly, it looks like a proposal to extend
>> std::tuple needs to discuss operator[] vs a free-standing function. We
>> could also mix it and get both by having operator[] call the free-standing
>> implementation.
>>
>>
>> On Sat, Apr 11, 2026 at 10:21 AM Muneem <itfllow123_at_[hidden]> wrote:
>>
>>> My response my Mr.Thiago Let's forget the bench marks for a second, and
>>> focus on the larger image of the limitations that I faced In implementing a
>>> dynamic type system. Micro dispatches may not matter on a small scale but
>>> it's like if if statements get slower then the effect is small in small
>>> projects and large in large ones. Similiarly if you were to access variants
>>> again and again and again, then you have the effect of the 13500% slower
>>> speed increased. Again, dynamic typing is not a esoteric branch of
>>> programming, infact as people move towards building large infrusture to
>>> connect AI tools to automated scripts and to help them operate those tools,
>>> we need real time systems, and real time systems often require flexibility
>>> as they become complex. In the case of my virtual machine, it was meant to
>>> be a simple way to build compilers but ended up having a whole large file
>>> for dynamic typing. I would argue that the reason Python is used to deal
>>> with large systems operated by AI or some other system is precisely because
>>> it supports dynamic typing(cuz it's interpreted). In the case of python,
>>> it's slow and the way it does dynamic typing is rather not strict
>>> enough(duck typing behaviours) that though could be mitigated with newer
>>> type constrained features are still causing issues in existing python code
>>> bases. C++ on the other hands can support dynamic typing in way that allows
>>> for strict closed set dynamic typing only. If that happens then people
>>> would have no reason to use python over C++ in the majority of cases,
>>> except the ones where you just want to automate a small task.
>>>
>>> On Fri, 10 Apr 2026, 8:02 pm Thiago Macieira via Std-Proposals, <
>>> std-proposals_at_[hidden]> wrote:
>>>
>>>> On Friday, 10 April 2026 04:34:24 Pacific Daylight Time Muneem via Std-
>>>> Proposals wrote:
>>>> > Why do we need to go in circles? Like std::variant is a union hence
>>>> not
>>>> > STRICTLY DYNAMICALLY TYPED.
>>>>
>>>> No, it isn't. That depends on the code you write. You can very well
>>>> operate
>>>> only on the type it currently has, without changing.
>>>>
>>>> For the purpose you've espoused -- using one of many possible list
>>>> implementations -- std::variant *works* *just* *fine*.
>>>>
>>>> From the analyses of the assembly generated by the compiler in the
>>>> benchmarks
>>>> you posted about a week ago, the difference is only where the "current
>>>> type" is
>>>> kept. With std::variant, since it is kept inside of the variant, the
>>>> code
>>>> emitted by the compiler ends up checking it every time. Quite likely,
>>>> if you
>>>> had two visitors back-to-back, the compiler would fail to realise it's
>>>> the
>>>> same current type and do two dispatches. That's a QoI problem and can
>>>> be fixed
>>>> in the compiler.
>>>>
>>>> With your external type selection, the compiler has an easier time
>>>> proving the
>>>> choice did not change and thus optimise the code to make a single
>>>> dispatch to
>>>> multiple visitors.
>>>>
>>>> That doesn't mean we need a new type. In real-world scenarios, the cost
>>>> of
>>>> extra dispatches is likely negligible -- as it was in the
>>>> micro-benchmarks.
>>>> There may be some edge cases where it is meaningful, but that does not
>>>> imply
>>>> the solution needs to be in the Standard Library. There are many
>>>> specialised
>>>> algorithms and containers that aren't due to their limited usefulness
>>>> to the
>>>> general public. Moreover, there is a cost in *adding* them: maintenance
>>>> by the
>>>> implementations, teachability, readability, etc.
>>>>
>>>> And more importantly, NONE of this implies we need a language change.
>>>> That
>>>> should be an orthogonal discussion.
>>>>
>>>> --
>>>> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>>>> Principal Engineer - Intel Data Center - Platform & Sys. Eng.
>>>> --
>>>> Std-Proposals mailing list
>>>> Std-Proposals_at_[hidden]
>>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>>
>>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>>
to provide specialization", I was wrong, like You can in fact do so:
template<typename T...>
struct variant;
template<typename T...>
struct variant<T&...>{
}
I am really really sorry for my mistake!!!!! I didn't think it through and
didn't test it using code as well.
On Sun, Apr 12, 2026 at 2:59 PM Muneem <itfllow123_at_[hidden]> wrote:
> ***question:***: how do you provide a class specialization specifically
> for reference T, without breaking the rule that a name used by a class cant
> be used for anything else in the same namespace/class/function scope.
> > No, actually this would change the current workings of std::optional.
> Currently, it throws if you call value() on it. Instead, we can also check
> if there is a valid option and then use operator* (which is UB to use if it
> doesn’t contain a value). The advantage of this approach is, that you do
> not force anybody to use exceptions. Some people really don’t like them.
> There is also no harm in constructing an empty optional when it is never
> used.
> **** Response ***:You have a point!
> >Usually, if the template parameter is a T& we would implement it as a
> pointer internally (just like you did). To the compiler, references and
> pointers look the same anyway (it’s just that you cannot reassign a
> reference to point to anything else). I think that this point is mostly
> solved already. As I said, I’m not sure about the status of the proposal
> for std::optional<T&>. But, exactly the same discussions would apply to
> std::variant<T&…>.
> **** Response ***: it's not problem solved if you allow references to be
> in tagged unions like std::variant because references are by nature have
> all their information known at compile time since its like a reference to
> an variable, making them be in unions requires you to implement some sort
> of support under the hood. There is a reason why references are only
> allowed in structs, not in anything that is "union like", since such
> support requires underlying pointers. Basically, it would be like
> variant<T* const....> except that it would have a specific new
> specialization that nothing depends on: std::variant<T..., reference_tag>
> and it can't hold nullptrpointers?
> >There is no branching needed. There are always two ways to specify
> conversion: one would be to write an std::variant::operator=. However, we
> would need to specify the desired type of the optional as a template
> parameter. The easier solution would be:
> template <Args&…>
> std::optional<T&>::optional(std::variant<Args…> &variant)
> : m_storage(std::holds_alternative<T&>(variant) ?
> std::get<T&>(variant) : std::nullopt)
> {}
> ****Response***: 1. std::variant::operator= would still need branching
> just like variants already have but would also need special support for
> having references in "tagged unions" , and 2. holds_alternative<> cant be
> passed references so again you do need some specialization of
> hold_alternative, and again, how do you do that!?
>
> A full proposal for this extension needs to discuss/consider a few things:
> 1. What kind of overloads do we need (const/non-const, &/&&)
> 2. Additional modifiers like constexpr and noexcept
> 3. Do we only propose this conversion just for std::optional<T&> or also
> for std::optional<T>
> 4. What should happen if there are duplicate types inside the variant
> (never happens with your use case)
> 5. Note that this does not compile if the type T& of the optional is not
> one of the types of the variant
> ****RESPONSE****: How about I say:
> 1. We can provide overloads for tuple<T..., Runtime_index_tag> and
> variant<T..., reference_tag>, like you cant I dont think I dont think you
> can just provide a
> std::variant<T...> without breaking the rule that a name used by a class
> cant be used for anything else in the same namespace/class/function scope.
> 2. subscripting operations and constructor for the tuple<T...,
> Runtime_index_tag> would be constexpr, with optimizations for the runtime
> execution be provided through a branch set by "std::is_constant_evaluated".
> For std::optional<T> , we need the same, that is a constexpr
> constructor/assignment function that checks whether the variant has the
> correct type or does it have any at all and throws a compiler error, while
> a runtime version throws an error. This would of course require a
> std::variant member consteval function "is compile time constructed" used
> by that branch(the one branched by is_constant_evaluated), and a
> std::variant constexpr constructor that sets the value returned by that to
> true in its own "is_constant_evaluated==true" branch, but by default that
> underlying value would be false. This provides a full set of optimizations
> if any index into the tuple is constexpr.
> 3,. I would say provide for both std::optional<T> and std::optional<T> so
> as to support some way of moving/copying the value of the variant.
> 4. tuple<T..., Runtime_index_tag> would have to return
> std::variant<enable_if<std::is_same_v< Is_t_in_set <T, T...>, t true_t
> >>...> as the return type of indexing, where in_t_in_set would obviously be
> classic bjarne stourstrup style stuff:
>
> struct false_t {};
>
> struct true_t {};
>
> template<typename T, typename... Tail>
>
> struct Is_t_in_set;
>
> template<typename T, typename Head_t, typename... Tail>
>
> struct Is_t_in_set<T, Head_t, Tail...> {
>
> using boolean = std::conditional_t<
>
> std::is_same_v<T, Head_t>,
>
> true_t,
>
> typename Is_t_in_set<T, Tail...>::boolean
>
> >;
>
> };
>
> template<typename T, typename Head_t>
>
> struct Is_t_in_set<T, Head_t> {
>
> using boolean = std::conditional_t<
>
> std::is_same_v<T, Head_t>,
>
> true_t,
>
> false_t
>
> >;
>
> };
> credits to him of course for such confusing(yet effective) techniques.
> 5. yeah, exactly, it should not compile if: type T passed to (as a
> template arg) optional is not one of the types of the variant and to
> enforce this, you could ofcourse use SFINAE:
> template<typename T_of_optional>
> struct optional< T_of_optional , reference_tag >{
> //like optional<T&> but it is possible to exist thanks to the extra
> reference_tag overload tag
> typename<typename T..., template <typename T..., typename Tag> Variant_t>
> enable_if<std::is_same_v< Is_t_in_set < T_of_optional , T...>, t true_t
> > && std::is_same_v<T, reference_tag >>optional( Variant_t <T...,
> reference_tag > ){
> //now copy
>
> }
> }
> again the code is just pseudo code, like just to give you an idea of what
> I think, so the syntax maybe wrong
>
>
> >For proposing std::variant<Ts&…> we should also discuss if a std::variant
> should only be allowed to be either specified on only Ts… or Ts&…, or if we
> allow a mixture of Ts and T-refs. (Certainly, for what you want just Ts&…
> would suffice.) I’m not sure what the use case for a mixture would be, but
> I also don’t see the point in artificially restricting them.
> ***Answer***: let's keep the separate, like technically a class can't know
> for sure if some type can be reference or by value without a tag or
> without different class names. Its not mechanically possible in the current
> language facilities for variadic templates.
> >Concerning the immutability of the selected type of a variant this is
> just handled by making the variable of type std::variant const. There is no
> std::variant::operator=() const, so we cannot reassign to a const
> std::variant. Unfortunately, right now we also cannot reassign a value of
> the proper type to a const std::variant (that’s just a syntactical/optical
> deficiency).
> ***Answer***: so the overload for std::variant<T...,
> reference_tag>::operator=() const should simply move/copy into the
> underlying object pointed to by the reference?
>
> >One more thing for std::variant: I want to be able to convert a
> std::variant<int&,float&> to a std::variant<int,float> and also to an
> std::optional<int>. This way the user of the type can choose between
> getting a reference into the tuple or a copy of the value. (We need to
> discuss if it makes sense to move values outside the tuple; this would be a
> trap for UB.)
> ***ANSWER***: It won't be in the sense that if std::variant<int,float> is
> const then you can only copy/assign to the underlying object whose type is
> chosen during construction. For std::optional, its an exception if the user
> prefers to be safe, but if he uses unsafe (but faster) methods then yeah,
> undefined behaviour.
>
> >Extending std::tuple with operator[] also needs one discussion: Do we
> only allow this if all the types inside the tuple are distinct? I don’t see
> it necessary for proposing this extension. However, I’d want for the
> implementation of operator[] to make the types of the std::variant returned
> to be distinct even if the types of std::tuple are not.
> ***ANSWER***: It does require a discussion, but what do you mean by
> "distinct"? like in what way? is the variant gonna handle them differently?
>
> On Sun, Apr 12, 2026 at 11:59 AM Simon Schröder <
> dr.simon.schroeder_at_[hidden]> wrote:
>
>>
>>
>> On Apr 11, 2026, at 2:23 PM, Muneem via Std-Proposals <
>> std-proposals_at_[hidden]> wrote:
>>
>>
>> On 4/10/26 20:01, Simon Schröder via Std-Proposals wrote:
>> >std::optional<int&> x = list[0];
>> Just to make sure that we are on the same page:
>> we both agree that "std::optional<int&> x = list[index];"
>> 1. std::optional<int&> 's constructor should throw an exception if the
>> variant returned by list[index] is not an int.
>>
>> No, actually this would change the current workings of std::optional.
>> Currently, it throws if you call value() on it. Instead, we can also check
>> if there is a valid option and then use operator* (which is UB to use if it
>> doesn’t contain a value). The advantage of this approach is, that you do
>> not force anybody to use exceptions. Some people really don’t like them.
>> There is also no harm in constructing an empty optional when it is never
>> used.
>>
>> 2. For std::variant<T&...> to work, we need support from the
>> implementation just like the support I needed for type_set<T...>, this
>> support would be import such that we can avoid the T& to be changed, and
>> since unions cant have references, the implementation would need to come up
>> with some internal implementation.
>>
>> Usually, if the template parameter is a T& we would implement it as a
>> pointer internally (just like you did). To the compiler references and
>> pointers look the same anyway (it’s just that you cannot reassign a
>> reference to point to anything else). I think that this point is mostly
>> solved already. As I said, I’m not sure about the status of the proposal
>> for std::optional<T&>. But, exactly the same discussions would apply to
>> std::variant<T&…>.
>>
>>
>> Note: the branching that I talked about for "std::variant<T&...>
>> specialization to to some std::optional<T&> at runtime" in my email to
>> Mr.David Brown is the checking in point one.
>>
>> There is no branching needed. There is always two ways to specify
>> conversion: one would be to write an std::variant::operator=. However, we
>> would need to specify the desired type of the optional as a template
>> parameter. The easier solution would be:
>> template <Args&…>
>> std::optional<T&>::optional(std::variant<Args…> &variant)
>> : m_storage(std::holds_alternative<T&>(variant) ?
>> std::get<T&>(variant) : std::nullopt)
>> {}
>>
>> A full proposal for this extension needs to discuss/consider a few things:
>> 1. What kind of overloads do we need (const/non-const, &/&&)
>> 2. Additional modifiers like constexpr and noexcept
>> 3. Do we only propose this conversion just for std::optional<T&> or also
>> for std::optional<T>
>> 4. What should happen if there are duplicate types inside the variant
>> (never happens with your use case)
>> 5. Note that this does not compile if the type T& of the optional is not
>> one of the types of the variant
>>
>> For proposing std::variant<Ts&…> we should also discuss if a std::variant
>> should only be allowed to be either specified on only Ts… or Ts&…, or if we
>> allow a mixture of Ts and T-refs. (Certainly, for what you want just Ts&…
>> would suffice.) I’m not sure what the use case for a mixture would be, but
>> I also don’t see the point in artificially restricting them.
>>
>> Concerning the immutability of the selected type of a variant this is
>> just handled by making the variable of type std::variant const. There is no
>> std::variant::operator=() const, so we cannot reassign to a const
>> std::variant. Unfortunately, right now we also cannot reassign a value of
>> the proper type to a const std::variant (that’s just a syntactical/optical
>> deficiency).
>>
>> One more thing for std::variant: I want to be able to convert a
>> std::variant<int&,float&> to a std::variant<int,float> and also to an
>> std::optional<int>. This way the user of the type can choose between
>> getting a reference into the tuple or a copy of the value. (We need to
>> discuss if it makes sense to move values outside the tuple; this would be a
>> trap for UB.)
>>
>> Extending std::tuple with operator[] also needs one discussion: Do we
>> only allow this if all the types inside the tuple are distinct? I don’t see
>> it necessary for proposing this extension. However, I’d want for the
>> implementation of operator[] to make the types of the std::variant returned
>> to be distinct even if the types of std::tuple are not.
>>
>>
>> On 4/10/26 20:01, Bjorne Reese via Std-Proposals wrote:
>> >> 2. Add operator[] to std::tuple which returns const std::variant<Ts&…>
>>
>> >Better yet, a free function that works with any tuple-like object.
>>
>> 1. I can agree that it will be convenient, but I would also love to
>> emphasize that there should be a specific member function for the specific
>> tuple<T&...> meant for runtime that has its own different implementation.
>>
>>
>> @Bjorne: I do understand what you are saying here and why. I’m personally
>> a little annoyed by the syntax of std::get. In general, I prefer the member
>> access syntax (and we didn’t get automatic lookup of free-standing
>> functions for this so far). Especially with the use of runtime indices it
>> would be more consistent with arrays, vectors, etc. when using operator[]
>> (and I like it better). Certainly, it looks like a proposal to extend
>> std::tuple needs to discuss operator[] vs a free-standing function. We
>> could also mix it and get both by having operator[] call the free-standing
>> implementation.
>>
>>
>> On Sat, Apr 11, 2026 at 10:21 AM Muneem <itfllow123_at_[hidden]> wrote:
>>
>>> My response my Mr.Thiago Let's forget the bench marks for a second, and
>>> focus on the larger image of the limitations that I faced In implementing a
>>> dynamic type system. Micro dispatches may not matter on a small scale but
>>> it's like if if statements get slower then the effect is small in small
>>> projects and large in large ones. Similiarly if you were to access variants
>>> again and again and again, then you have the effect of the 13500% slower
>>> speed increased. Again, dynamic typing is not a esoteric branch of
>>> programming, infact as people move towards building large infrusture to
>>> connect AI tools to automated scripts and to help them operate those tools,
>>> we need real time systems, and real time systems often require flexibility
>>> as they become complex. In the case of my virtual machine, it was meant to
>>> be a simple way to build compilers but ended up having a whole large file
>>> for dynamic typing. I would argue that the reason Python is used to deal
>>> with large systems operated by AI or some other system is precisely because
>>> it supports dynamic typing(cuz it's interpreted). In the case of python,
>>> it's slow and the way it does dynamic typing is rather not strict
>>> enough(duck typing behaviours) that though could be mitigated with newer
>>> type constrained features are still causing issues in existing python code
>>> bases. C++ on the other hands can support dynamic typing in way that allows
>>> for strict closed set dynamic typing only. If that happens then people
>>> would have no reason to use python over C++ in the majority of cases,
>>> except the ones where you just want to automate a small task.
>>>
>>> On Fri, 10 Apr 2026, 8:02 pm Thiago Macieira via Std-Proposals, <
>>> std-proposals_at_[hidden]> wrote:
>>>
>>>> On Friday, 10 April 2026 04:34:24 Pacific Daylight Time Muneem via Std-
>>>> Proposals wrote:
>>>> > Why do we need to go in circles? Like std::variant is a union hence
>>>> not
>>>> > STRICTLY DYNAMICALLY TYPED.
>>>>
>>>> No, it isn't. That depends on the code you write. You can very well
>>>> operate
>>>> only on the type it currently has, without changing.
>>>>
>>>> For the purpose you've espoused -- using one of many possible list
>>>> implementations -- std::variant *works* *just* *fine*.
>>>>
>>>> From the analyses of the assembly generated by the compiler in the
>>>> benchmarks
>>>> you posted about a week ago, the difference is only where the "current
>>>> type" is
>>>> kept. With std::variant, since it is kept inside of the variant, the
>>>> code
>>>> emitted by the compiler ends up checking it every time. Quite likely,
>>>> if you
>>>> had two visitors back-to-back, the compiler would fail to realise it's
>>>> the
>>>> same current type and do two dispatches. That's a QoI problem and can
>>>> be fixed
>>>> in the compiler.
>>>>
>>>> With your external type selection, the compiler has an easier time
>>>> proving the
>>>> choice did not change and thus optimise the code to make a single
>>>> dispatch to
>>>> multiple visitors.
>>>>
>>>> That doesn't mean we need a new type. In real-world scenarios, the cost
>>>> of
>>>> extra dispatches is likely negligible -- as it was in the
>>>> micro-benchmarks.
>>>> There may be some edge cases where it is meaningful, but that does not
>>>> imply
>>>> the solution needs to be in the Standard Library. There are many
>>>> specialised
>>>> algorithms and containers that aren't due to their limited usefulness
>>>> to the
>>>> general public. Moreover, there is a cost in *adding* them: maintenance
>>>> by the
>>>> implementations, teachability, readability, etc.
>>>>
>>>> And more importantly, NONE of this implies we need a language change.
>>>> That
>>>> should be an orthogonal discussion.
>>>>
>>>> --
>>>> Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
>>>> Principal Engineer - Intel Data Center - Platform & Sys. Eng.
>>>> --
>>>> Std-Proposals mailing list
>>>> Std-Proposals_at_[hidden]
>>>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>>>
>>> --
>> Std-Proposals mailing list
>> Std-Proposals_at_[hidden]
>> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>>
>>
Received on 2026-04-12 10:05:32
