$include_dir="/home/hyper-archives/boost/include"; include("$include_dir/msg-header.inc") ?>
Subject: Re: [boost] [convert] no-throw and fallback feature
From: Gordon Woodhull (gordon_at_[hidden])
Date: 2011-05-10 17:29:33
On May 10, 2011, at 3:55 PM, Vicente BOTET wrote:
> If opt_tie is implicitly convertible to a bool as it is optional 
> 
>> // 2
>> int i(fallback);
>> bool b;
>> opt_tie(i, b) = convert_to>(s);
>> if (!b)
>> {
>> std::cerr << "using fallback\n";
>> }
> 
> can be written as
> 
> // 2 b
> int i(fallback);
> if (!( opt_tie(i) = convert_to>(s)) )
> {
> std::cerr << "using fallback\n";
> }
> 
> I agree however that //2 could be easier to read. Do you think that opt_tie must be implicitly convertible to bool or not?
I think opt_tie should behave as if it's optional<T>&.  I am not sure why one would want to chain assignments in this case, but it should be possible.
Unfortunately because optional<T&> wants to rebind its reference it's not possible to do as boost::tie does.  
So, it's probably a wrapper.  This works; I'm not sure if it's optimal:
#include <boost/optional.hpp>
#include <iostream>
using boost::optional;
using std::cout;
using std::endl;
/*
// does not work because optional<T&> wants to rebind its reference on assignment
template<typename T>
optional<T&> opt_tie(T &x) {
  return optional<T&>(x);
}
*/
template<typename T>
class opt_tie_type {
  T &x_;
public:
  opt_tie_type(T &x) : x_(x) {}
  const optional<T> operator=(optional<T> const& y) {
    if(y)
      x_ = y.get();
    return y;
  }
};
template<typename T>
opt_tie_type<T> opt_tie(T &x) {
  return opt_tie_type<T>(x);
}
int main() {
  optional<int> has(9), hasnt;
  int x;
  if(opt_tie(x) = has)
    cout << "has " << x << endl;
  x = 17;
  if(!(opt_tie(x) = hasnt))
    cout << "hasn't " << x << endl;
  //chained assignment
  int y;
  optional<int> opt = opt_tie(y) = has;
  if(opt)
    cout << "still has " << opt.get() << endl;
  return 0;
}