0

I'm trying to force right-associativity when using a left-associative C++ operator (like operator+()) but I'm "dying" just before the end (see the last static_assert).

Having some objects A a; B b; C c; D d; and the overloaded operator+(), I would like to write a+b+c+d and behind the scene to have X<A, X<B, X<C,D>>> (X being a custom binary op)

Does anybody have any hint? Or different approach?

Thanks in advance!

live example: https://godbolt.org/z/58dM6Ws4b

#include <cstdio>
#include <utility>

struct Tag{};//for class tagging
struct A: public Tag{};
struct B: public Tag{};
struct C: public Tag{};
struct D: public Tag{};

struct X0{};
template<typename L, typename R>
struct X: public X0{//binary op to force right-associativity
    using TL = L;
    using TR = std::conditional_t<std::is_base_of_v<Tag,L> && std::is_base_of_v<Tag,R>, R&, R>;
    L& l;
    TR r;
    X(L&l, R&r): l{l}, r{r}{}
    X(L&l, R&&r): l{l}, r{std::forward<TR>(r)}{}
    X(L&&l, R&r): X{l.l, X{l.r,r}} {}
};

template<std::derived_from<Tag> L, std::derived_from<Tag> R>
auto operator+(L& l, R& r){return X{l, r};} //for: a+b
template<std::derived_from<X0> L, std::derived_from<Tag> R>
auto operator+(L&& l, R&r){return X{l.l, X{l.r,r}};} //for: a+b+c

//================================================================
int main(){
    A a; B b; C c; D d;
    printf("-------- a+b\n");
    auto x2 = a+b;
    printf("-------- a+b+c\n");
    auto x3 = a+b+c; // <=> (a+b)+c
    static_assert(std::is_same_v<decltype(x3), X<A, X<B,C>>>);
    printf("-------- a+b+c+d\n");
    auto x4 = a+b+c+d; // <=> ((a+b)+c)+d
    //static_assert(std::is_same_v<decltype(x4), X<A, X<B, X<C,D>>>>); //<-- this fails
    return 0;
}
Solo
  • 105
  • 8

0 Answers0