-
Notifications
You must be signed in to change notification settings - Fork 78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Problem with std::unique_ptr #67
Comments
Sorry for delay with an answer - was on a small vacation. The main problem here is that std::unique_ptr is a non-copyable type. When you declare var you essentially declare a variable that will hold a value of type ExprPtr, that value will be assigned from the value of the subject during matching and since the subject is of non-assignable type, you get an error. To avoid copying std::unique_ptr, you can try to bind by reference that smart pointer, however in current C++ this will become ugly for the RHS as there is no real way of creating perfect proxy: int evl(const Expr& e)
{
var<const ExprPtr&> e1, e2;
var<int> n;
Match(e)
{
Case(C<Value> (n) ) return n;
Case(C<Plus> (e1,e2)) return evl(*e1.m_value->get()) + evl(*e2.m_value->get());
Case(C<Minus> (e1,e2)) return evl(*e1.m_value->get()) - evl(*e2.m_value->get());
Case(C<Times> (e1,e2)) return evl(*e1.m_value->get()) * evl(*e2.m_value->get());
Case(C<Divide>(e1,e2)) return evl(*e1.m_value->get()) / evl(*e2.m_value->get());
}
EndMatch
XTL_UNREACHABLE; // To avoid warning that control may reach end of a non-void function
} You can also make it a bit prettier by changing bindings to retrieve the pointer from the underlaying unique_ptr. Just remember here that arguments to Members macro can be either:
It's the last one we use here (only provide specializations for const case, you can derive similar for non-const): template <typename C>
const Expr* get_e1(const C* subject)
{
return subject->e1.get(); // Notice call to get on std::unique_ptr here
}
template <typename C>
const Expr* get_e2(const C* subject)
{
return subject->e2.get();
}
namespace mch ///< Mach7 library namespace
{
template <> struct bindings<Value> { Members(Value::value); };
template <> struct bindings<Plus> { Members(get_e1<Plus> , get_e2<Plus>); };
template <> struct bindings<Minus> { Members(get_e1<Minus> , get_e2<Minus>); };
template <> struct bindings<Times> { Members(get_e1<Times> , get_e2<Times>); };
template <> struct bindings<Divide>{ Members(get_e1<Divide>, get_e2<Divide>); };
} // of namespace mch with these bindings you can simply write: int evl(const Expr& e)
{
var<const Expr*> e1, e2; // Note we don't bind std::unique_ptr here, which is non-copyable, but its pointer's value
var<int> n;
Match(e)
{
Case(C<Value> (n) ) return n;
Case(C<Plus> (e1,e2)) return evl(*e1) + evl(*e2);
Case(C<Minus> (e1,e2)) return evl(*e1) - evl(*e2);
Case(C<Times> (e1,e2)) return evl(*e1) * evl(*e2);
Case(C<Divide>(e1,e2)) return evl(*e1) / evl(*e2);
}
EndMatch
XTL_UNREACHABLE; // To avoid warning that control may reach end of a non-void function
} Is that closer to what you are looking for? I added file example04-smart-ptr-bind-ptr.cpp demonstrating it - compare it to the original example for differences. |
Much closer, thank you! |
example04-smart-ptr.cpp demonstrates how one can match on unique_ptr values. The example, however only describes the usage of adapter aided matching using the reference operator. Below that, there is another example showing an alternate matching technique:
The code snippet pasted above does not compile. However, that's exactly what I need, as I cannot use references in my current context.
Is there any way to get the desired behaviour to work?
The text was updated successfully, but these errors were encountered: