You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I expected to be able to find a way to make the poly interface comparable, so one could compare the value stored in it. It's reasonably easy to add a way to check if the types are the same (by adding a function to make them return the type_index of type inside the poly), then return false in the comparison operator when they are not, but I've not been able to find a way to compare the same types by calling the operator== of the right one when those are the same. Example:
#include<iostream>
#include<typeindex>
#include"te.hpp"using std::cout;
using std::endl;
namespacete= boost::te;
structOne {
booloperator==(const One&) const {
returntrue;
}
};
structTwo {
booloperator==(const Two&) const {
returntrue;
}
};
structComparable : te::poly<Comparable> {
using te::poly<Comparable>::poly;
booloperator==(const Comparable& other) const {
auto body = [](autoconst& self, Comparable const& other) {
// `self` is the "downcast" type (One/Two), but `other` is// Comparable, the interface. We need to figure out how to get the// right type.// This doesn't really work, as the types are never the same.// if constexpr (std::is_same_v<decltype(self), decltype(other)>)// return self == other;// return false;// This doesn't compile, as One or Two can (and should) only compare// with themselves, but `other` is of type Comparable.// return self == other;constbool sameType = other.type() == std::type_index(typeid(self));
// Not ideal, as we know for sure that we are not the same when the// type is not the same, but we don't know if two objects of the// same type are the same. We need to cast `other` to the type of// `self`. Now `other` is Comparable, while `self` is the "real"// object put into a Comparable (e.g. One, Two).// return sameType;// The next lines are the further I've been able to get to.if (!sameType)
returnfalse;
// Attempt to cast `other` to the same type of `self`.using SelfType = decltype(self);
auto innerBody = [] (autoconst& innerSelf, const SelfType& innerOther) {
ifconstexpr (std::is_same_v<decltype(innerSelf), SelfType>)
returnfalse;
elsereturn innerSelf == innerOther;
};
// Crashes. I tried to swap `other` and `self` with respect to the// other te::call, so I could get the `Comparable const& other` cast// to the right type inside the poly, and use the `operator==` of// `One` or `Two`.return te::call<bool>(innerBody, other, self);
};
return te::call<bool>(body, *this, other);
}
std::type_index type() const {
return te::call<std::type_index>([](autoconst& self) {
returnstd::type_index(typeid(self));
}, *this);
}
};
intmain()
{
Comparable one = One{};
Comparable two = Two{};
cout << one.type().name() << endl;
cout << two.type().name() << endl;
cout << "one==one " << (one == one) << endl;
cout << "one==two " << (one == two) << endl;
cout << "two==two " << (two == two) << endl;
}
Actual Behavior
With the code as in the cample above, it crashes at runtime, and I could not properly understand why.
Alternatively, I would consider that adding something like te::cast<T>, with a similar behavior as any_cast, would make sense. It would allow one to do the usual operations that one can do with std::any and "normal" polymorphism. The AnyAny library seems to provide that functionality (both the cast, and a default way to make the polymorphic value comparable via a built-in API for making it provide the operator).
Expected Behavior
I expected to be able to find a way to make the poly interface comparable, so one could compare the value stored in it. It's reasonably easy to add a way to check if the types are the same (by adding a function to make them return the
type_index
of type inside the poly), then return false in the comparison operator when they are not, but I've not been able to find a way to compare the same types by calling theoperator==
of the right one when those are the same. Example:Actual Behavior
With the code as in the cample above, it crashes at runtime, and I could not properly understand why.
Alternatively, I would consider that adding something like
te::cast<T>
, with a similar behavior asany_cast
, would make sense. It would allow one to do the usual operations that one can do withstd::any
and "normal" polymorphism. The AnyAny library seems to provide that functionality (both the cast, and a default way to make the polymorphic value comparable via a built-in API for making it provide the operator).Steps to Reproduce the Problem
Just trying the example above.
Specifications
Thank you!
The text was updated successfully, but these errors were encountered: