[optional] optional<T &> and the arrow operator

I’ve discovered that you can’t use the arrow operator with an object of type optional<T &>; For instance , the following code fails: vector<double> v; optional<vector<double> &> pv(v); pv->push_back(2); The code (*pv).push_back(2) succeeds. On MSVC 7.1 on Windows XP I get the following error message: (I get a similar one using gcc 3.4 on Unix). c:\code\boost\optional\optional.hpp(371) : error C2664: 'boost::optional_detail::optional_base<T>::pointer_const_type boost::optional_detail::optional_base<T>::cast_ptr(const boost::optional_detail::optional_base<T>::internal_type *,boost::optional_detail::optional_base<T>::is_not_reference_tag) const' : cannot convert parameter 2 from 'boost::integral_constant<bool,true>' to 'boost::optional_detail::optional_base<T>::is_not_reference_tag' with [ T=std::vector<double> & ] and [ T=std::vector<double> & ] No constructor could take the source type, or constructor overload resolution was ambiguous c:\code\boost\optional\optional.hpp(371) : while compiling class-template member function 'boost::optional_detail::optional_base<T>::pointer_type boost::optional_detail::optional_base<T>::get_ptr_impl(void)' with [ T=std::vector<double> & ] c:\code\boost\optional\optional.hpp(407) : see reference to class template instantiation 'boost::optional_detail::optional_base<T>' being compiled with [ T=std::vector<double> & ] c:\code\Networks\Computations\CppComputations\Forecasting\auto_DFS_2_00_computation.cpp(16) : see reference to class template instantiation 'boost::optional<T>' being compiled with [ T=std::vector<double> & ] Joe Gottman

Hi Joe,
I've discovered that you can't use the arrow operator with an object of type optional<T &>; For instance , the following code fails:
vector<double> v; optional<vector<double> &> pv(v); pv->push_back(2);
The code
(*pv).push_back(2)
succeeds.
Thanks for the report. I'll look into it ASAP. Best -- ------ Fernando Cacciola SciSoft http://certuscode.wordpress.com http://fcacciola.50webs.com http://fcacciola.wordpress.com

Fernando Cacciola wrote:
Hi Joe,
I've discovered that you can't use the arrow operator with an object of type optional<T &>; For instance , the following code fails:
vector<double> v; optional<vector<double> &> pv(v); pv->push_back(2);
The code
(*pv).push_back(2)
succeeds.
Thanks for the report.
I'll look into it ASAP.
Has there been any progress on fixing this problem? It would be great if this could be fixed for version 1.34 (I definitely consider it to be a bug). Thanks, Joe Gottman

Joe Gottman wrote:
Fernando Cacciola wrote:
Hi Joe,
I've discovered that you can't use the arrow operator with an object of type optional<T &>; For instance , the following code fails:
vector<double> v; optional<vector<double> &> pv(v); pv->push_back(2);
The code
(*pv).push_back(2)
succeeds.
Thanks for the report.
I'll look into it ASAP.
Has there been any progress on fixing this problem? It would be great if this could be fixed for version 1.34 (I definitely consider it to be a bug).
Sorry for the long delay. I just commited the fix to RC_1_34_0, just right on time before the code freeze tonight. Best -- ------ Fernando Cacciola SciSoft http://certuscode.wordpress.com http://fcacciola.50webs.com http://fcacciola.wordpress.com

On 2/9/07, Mathias Gaunard <mathias.gaunard@etu.u-bordeaux1.fr> wrote:
Joe Gottman a écrit :
I've discovered that you can't use the arrow operator with an object of type optional<T &>
Wouldn't it be better to simply use T* in that case?
Why would it? T* and T& have very different semantics. best regards, -- Felipe Magno de Almeida

Felipe Magno de Almeida wrote:
Why would it? T* and T& have very different semantics.
An optional T& has closer semantics to T* than a non-optional one. The most important thing, however, is that it will be more efficient given the implementation of optional (optional could eventually fix that with a specialization).

On 2/9/07, Mathias Gaunard <mathias.gaunard@etu.u-bordeaux1.fr> wrote:
Felipe Magno de Almeida wrote:
Why would it? T* and T& have very different semantics.
An optional T& has closer semantics to T* than a non-optional one.
Didn't understand what you mean. Could you rephrase?
The most important thing, however, is that it will be more efficient given the implementation of optional (optional could eventually fix that with a specialization).
That's not always the most important thing :-P best regards, -- Felipe Magno de Almeida

On 2/9/07, Felipe Magno de Almeida <felipe.m.almeida@gmail.com> wrote:
On 2/9/07, Mathias Gaunard <mathias.gaunard@etu.u-bordeaux1.fr> wrote:
Felipe Magno de Almeida wrote:
Why would it? T* and T& have very different semantics.
An optional T& has closer semantics to T* than a non-optional one.
Didn't understand what you mean. Could you rephrase?
An optional<T&> has nearly the same semantics as a T*. I think the only thing it's missing is pointer arithmetic, and it may be a little more clear that optional<T&> is non-owning (though less clear that it's Assignable). So I'm not sure either why anyone should use optional<T&> instead of T*. -- Namasté, Jeffrey Yasskin

On 2/12/07, Jeffrey Yasskin <jyasskin@google.com> wrote:
On 2/9/07, Felipe Magno de Almeida <felipe.m.almeida@gmail.com> wrote:
On 2/9/07, Mathias Gaunard <mathias.gaunard@etu.u-bordeaux1.fr> wrote:
Felipe Magno de Almeida wrote:
Why would it? T* and T& have very different semantics.
An optional T& has closer semantics to T* than a non-optional one.
Didn't understand what you mean. Could you rephrase?
An optional<T&> has nearly the same semantics as a T*. I think the only thing it's missing is pointer arithmetic, and it may be a little more clear that optional<T&> is non-owning (though less clear that it's Assignable). So I'm not sure either why anyone should use optional<T&> instead of T*.
I would say because of the ownership, but you said yourself.
-- Namasté, Jeffrey Yasskin
-- Felipe Magno de Almeida

On 2/13/07, Felipe Magno de Almeida <felipe.m.almeida@gmail.com> wrote:
On 2/12/07, Jeffrey Yasskin <jyasskin@google.com> wrote:
On 2/9/07, Felipe Magno de Almeida <felipe.m.almeida@gmail.com> wrote:
On 2/9/07, Mathias Gaunard <mathias.gaunard@etu.u-bordeaux1.fr> wrote:
Felipe Magno de Almeida wrote:
Why would it? T* and T& have very different semantics.
An optional T& has closer semantics to T* than a non-optional one.
Didn't understand what you mean. Could you rephrase?
An optional<T&> has nearly the same semantics as a T*. I think the only thing it's missing is pointer arithmetic, and it may be a little more clear that optional<T&> is non-owning (though less clear that it's Assignable). So I'm not sure either why anyone should use optional<T&> instead of T*.
I would say because of the ownership, but you said yourself.
I use optional<T&> for optional parameters to functions. It makes the interface cleaner than having a pointer (no need for the caller to use the address-of operator), it is more self-documenting and of course it makes ownership cleaner. Also, if you have more than one parameters, the syntax to skip an optional one is cleaner: foo(optional<A&> = optional<A&>(), optional<B&> = optional<B&>()); ... B x; foo(none, x); Instead of: foo2(A*, B*); ... B x; foo2(0, &x); // ^-- I'm passing an integer or a pointer? In fact by just looking at the prototype of foo2 you do not even know if you are allowed to pass a null pointer. Finally, an assert when dereferencing an empty optional (at least in debug mode) is much much better than a segmentation fault when dereferencing a null pointer. Anyways, I think that enabling operator-> for optional<T&> would be useful. I was surprised too wen it failed to compile. gpd
participants (6)
-
Felipe Magno de Almeida
-
Fernando Cacciola
-
Giovanni Piero Deretta
-
Jeffrey Yasskin
-
Joe Gottman
-
Mathias Gaunard