nested template type casting

I'm trying to figure out how to add typecast operator to the following nested class to allow the main to compile, but I can't figure what is needed.The last assignment in main is causing the problem. Note that the next to last assignment uses type casting to make it work. I suspect I need to define a typecast-operator for the 'add' class, but how?.

Sorry for the long listing, but this is as simple as I know how to make it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#include <iostream>
using namespace std;

template <char I> struct index { };

template <char I, char J> struct marker;

// simple class with just a 2 element int array
struct A {
  A() { }
  A(int i, int j) { a[0] = i; a[1] = j; }
  A(const A& x) { a[0] = x(0); a[1] = x(1); }

  template<char I, char J>
  marker<I,J> operator()(const index<I>&, const index<J>&) {
    return marker<I,J>(*this);
  }

  friend std::ostream& operator<<(std::ostream& os, const A& x) {
    return os << '{' << x.a[0] << ',' << x.a[1] << '}';
  }

  int& operator()(int i) { return a[i]; }
  const int& operator()(int i) const { return a[i]; }

private:
  int a[2];
};

template <char I, char J>
struct marker {
  const int DI;
  const int DJ;
  
  marker(A& a) : myA(a), DI(1), DJ(0) { }
  marker(A& a, const int i, const int j) : myA(a), DI(i), DJ(j) { }
  marker(const marker& m) : myA(m.myA), DI(m.DI), DJ(m.DJ) { }

  // cast I,J => J,I
  operator marker<J,I>() const {
    return marker<J,I>(myA,DJ,DI);
  }

  marker& operator=(const marker& m) {
    myA(0) = m(0);
    myA(1) = m(1);
    return *this;
  }

  // returns the i'th or (1-i)'th element of myA
  int operator()(int i) const {
    return myA(i*DI + (1-i)*DJ);
  }

  // collects addition arguments
  template<class LHS, class RHS>
  struct add {
    const LHS& lhs;
    const RHS& rhs;

    add(const LHS& l, const RHS& r) : lhs(l), rhs(r) { }

    // actually does the adding recursively
    int operator()(int i) const {
      return lhs(i) + rhs(i);
    }
    
  add< add,marker > operator+(const marker& b) const {
      return add< add,marker >(*this,b);
    }
  };

  add< marker,marker > operator+(const marker& b) const {
    return add< marker,marker >(*this,b);
  }

  template <class LHS, class RHS>
  void operator=(const add< LHS, RHS>& expr) {
    myA(0) = expr(0);
    myA(1) = expr(1);
  }

private:
  A& myA;
};


int main() {
  index<'i'> i;
  index<'j'> j;

  A a(1,2), b;

  b(i,j) = a(j,i);
  cout << b << endl; // "{2,1}"

  b(i,j) = a(i,j) + a(j,i);
  cout << b << endl; // "{3,3}"

  b(i,j) = (marker<'i','j'>) a(j,i) + a(i,j); // OK if explicitly type-cast first argument
  cout << b << endl;  // "{3,3}"

  b(i,j) = a(j,i) + a(i,j); // Fails to compile.
  cout << b << endl;  // expecting "{3,3}"

  return 0;
}
I think this line is causing you the problem
A(const A& x) { a[0] = x(0); a[1] = x(1); }


it should be
1
2
int m[2] = { 2 , 3 } ; 
 A(const m& x) { a[0] = x[0]; a[1] = x[1]; }


or

 
 A(const A& x) { a[0] = x.a[0]; a[1] = x.a[1]; }



please correct me if i am wrong .
Last edited on
No, that is not the cause of the problem. Your first suggestion doesn't make much sense to me and your second suggestion is functionally equivalent to the original code. Thanks for trying though.
[SOLVED]

Just needed to add the following member to class marker:

1
2
3
4
5
6
 
template <class LHS>
void operator=(const typename marker<J,I>::template add< LHS, marker<J,I> >& expr) {
    myA(0) = expr(0);
    myA(1) = expr(1);
}
yuck, ¿what is that code for?
Topic archived. No new replies allowed.