I haven't used C++ Templates and I am getting multiple syntax errors

Pages: 12
I'll wait for mbozzi to respond. I stated earlier that part of the code was already there. Not an option to remove it.
If you have to have that, then this suggests heavily that you are meant to use it? That you're meant to use the inheritance?

The fact that you have completely ignored it and done something else entirely - is that going to be a problem?
That part of the code was given to me by someone else for me to solve and so was the code in main. I only defined all the functions to make the code work in main. What is the problem with doing that?
There is a problem of redundancy. A variable with type DataContainer<N> contains two std::array<double, N> subobjects. The first subobject is the base class subobject, and the second is the member subobject.

If you must publicly inherit from a specialization of std::array, get rid of the member arr and manipulate the base class subobject instead.
Last edited on
That is one of the parts I struggled with in this program. I cannot add a name to the std::array<> on line 15. Where and how should I name the array that can be used by the functions ?
It doesn't need a name. Your class is-a array, so just use the array functions directly through your object.

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
#include <iostream>
#include <array>
using namespace std;

template<int Width>
class Data : public array<double, Width>
{
public:
    Data() : array<double,Width>{} // zero array
    {}
};

int main()
{
    Data<10> data;

    data[3] = 7; // using std::array::operator[]()

    // using std::array::size()
    cout << "size: " << data.size() << '\n';

    // using begin, end, etc.
    for (double d: data) cout << d << ' ';
    cout << '\n';
}

Where and how should I name the array that can be used by the functions ?


You can use member functions of your base class to access it
For example, you can use this->data() to get a pointer to the first element of the underlying std::array.

You could also write a function to convert this into a pointer to std::array, but for the most part plain range-based loops will suffice to do most of the work in a way that makes this concern irrelevant.

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
#include <cmath>
#include <iostream>
#include <string>
#include <array>

int const DATAROW_LENGTH = 4;

using namespace std;

template <size_t T_width>
class DataContainer : public array<double, T_width>
{
public:
    // N.B.: no operator=, no copy constructor, no destructors are written here: 
    // the compiler-generated versions do the right thing.
	
	DataContainer& Powr(double power)
	{ 
	    // For each element 'elt' in this std::array
	    //  (this object IS A std::array<>, as implied by public inheritance)
		for (double& elt: *this)
			elt = std::pow(elt, power);
			
		return *this;
	}
	
	DataContainer& Squrt()
	{
		for (double& elt: *this)
		    elt = std::sqrt(elt);
		    
		return *this;
	}
	
    // Compound assignments should always return references
    // Canonically, use the compound-assignment operators (for example -=, +=, <<=) 
    // to implement the corresponding operator (-, +, <<)
    //
    // N.B.: compound assignment operators return references to their left-side operand
    // In these cases, *this is the left-side operand 
	DataContainer& operator-=(DataContainer const& rhs)
	{
	    // Access std::array's member functions with this->memberfunction()
	    // You need to use 'this->' in this particular case
	    // Because of technical minutiae related to name lookup.
		for (std::size_t i = 0; i < T_width; i++)
			this->data()[i] = this->data()[i] - rhs[i];
		
		return *this;
	}

	DataContainer& operator/=(double value)
	{
		for (double& elt: *this)
		    elt /= value;
		    
		return *this;
	}

	DataContainer& operator+=(DataContainer const& rhs)
	{
		for (std::size_t i = 0; i < T_width; i++)
			this->data()[i] = this->data()[i] + rhs[i];
	
		return *this;
	}

	
	void printArray() const
	{
		for (double const& elt: *this)
		    std::cout << elt << ' ';
		std::cout << '\n';
	}	
};

// N.B.: pass lhs by value, so that a copy of it is made
// Use -= directly instead of duplicating code
//
// There is no need for these to be friend functions
// since they need no access to the private implementation of DataContainer.
template <size_t T_width>
DataContainer<T_width> operator-(DataContainer<T_width> lhs, DataContainer<T_width> const& rhs)
{
    return lhs -= rhs;
}

template <size_t T_width>
DataContainer<T_width> operator+(DataContainer<T_width> lhs, DataContainer<T_width> const& rhs)
{
    return lhs += rhs;
}

template <size_t T_width>
DataContainer<T_width> operator/(DataContainer<T_width> lhs, double value) 
{
    return lhs /= value;
}
Last edited on
Okay. I understand. But how will all the data in the array of each object in main get saved?

I re-wrote one of the functions. I'm not sure if it is correct. I don't think it is correct.
1
2
3
4
5
6
7
8
9
10
11
12

friend DataContainer operator-(const DataContainer<T_width>& rhs,
                            const DataContainer<T_width>& rhs2)
	{
		DataContainer<T_width> temp;

		for (int i = 0; i < T_width; i++)
		{
			temp[i] = rhs[i] - rhs2[i];
		}
		return temp;
	}


I also changed the constructor function:

1
2
3
4
5
6
7
8
DataContainer() :array<double, T_width>{}
	{		
		DataContainer<T_width> d;
		for (int i = 0; i < T_width; i++)
		{
			d[i] = 0;
		}
	}
Okay. I see. I wrote the last post before I saw the post before it. Thank you. I will try what you suggested.
I tried what you suggested above. The program compiles and runs without errors, but I don't see any data on the screen. The arrays seem to be empty. I also tried using this->_Elem[i] instead of this->data()[i]. I am not sure what I am doing wrong.

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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151

#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <string>
#include <array>
#pragma warning(disable: 4522)

#define DATAROW_LENGTH 4
using namespace std;

template<size_t T_width>

class DataContainer : public array<double, T_width>
{
	
public:
	

	DataContainer() :array<double, T_width>{}
	{			
		for (int i = 0; i < T_width; i++)
		{
			this->data()[i] = 0.0;
		}
	}
	
	void fill(double input)
	{
		this->fill(input);
	}
	DataContainer Powr( int power)
	{
		for (size_t i = 0; i < T_width; i++)
		{
			this->data()[i] = pow(this->data()[i], power);
		}
		return *this;
	}
	DataContainer Squrt()
	{
		
		for (size_t i = 0;i<T_width;i++)
		{
			this->data()[i] =  std::sqrt(this->data()[i]);
		}
		return *this;
	}	
	DataContainer operator-=(const DataContainer& rhs)
	{
		
		for (int i = 0; i < T_width; i++)
		{
			this->data()[i] -= rhs[i];
		}
		return *this;
	}
	
	
	DataContainer& operator+=( DataContainer& rhs)
	{
		DataContainer<T_width> temp;

		for (int i = 0; i < T_width; i++)
		{
			this->data()[i] = this->data()[i] + rhs[i] ;
		}
		return *this;
	}
	void printArray()const
	{		
		for (unsigned int i = 0; i < this->size(); i++)
		{
			cout << this->data()[i] << endl;
		}
	}
	DataContainer operator-(const DataContainer<T_width>& rhs)
	{
		for (size_t i = 0; i < T_width; i++)
		{
			this->data()[i] -= rhs[i];
		}
		return *this;
	}
	DataContainer<T_width> operator/( int value)
	{
		for (size_t i = 0; i < T_width; i++)
		{
			this->data()[i] /=  value;
		}
		return *this;
	}
	DataContainer<T_width> operator+(const DataContainer<T_width>& rhs)
	{
		
		for (size_t i = 0; i <T_width; i++)
		{
			this->data()[i] = this->data()[i] + rhs[i];
		}
		
		return *this;
	}
};

int main(int argc, char** argv)
{	
	typedef DataContainer< DATAROW_LENGTH > DataRow;//typedef is an alias name
	DataRow d1, d2, d3;	
	
	d1.fill(10); 
	cout << "AFTER d1 FILL" << endl;
	d1.printArray();

	d2.fill(20);
	cout << "AFTER d2 FILL" << endl;
	d2.printArray();

	d3 = d1 + d2;		// Elementwise addition
	cout << "======D3 AFTER d3 = d1+d2" << endl;
	d3.printArray();
	
	d3 = d1 - d2;		// Elementwise subtraction
	cout << "===========D3 AFTER d3 = d1-d2" << endl;
	d3.printArray();	

	d3 = d1 / 5;		// Divide all elements by a constant
	cout << "=======D3 AFTER d3 = d1/5" << endl;
	d3.printArray();
	
	cout << " =============D1========" << endl;
	d1.printArray();
	
	d3 += d1; 		// Compound assignment
	cout << "===============D3 AFTER d3 += d1" << endl;
	d3.printArray();

	d3 -= d2;
	cout << "===============D3 AFTER d3 -= d2" << endl;
	d3.printArray();

	d3 = d1.Powr(2); 	// Raise all elements to a constant power(d1 unchanged)
	cout << "===============D3 AFTER d3 = d1.pow(2)" << endl;
	d3.printArray();

	d3 = d2.Squrt(); 	// Square root of element (d2 unchanged)
	cout << "==============D3 AFTER d3 = d2.sqrt" << endl;
	d3.printArray();
	
	return 0;
}
fill() was recursive.
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <array>
#include <cmath>
#include <string>
#include <iostream>
#pragma warning(disable: 4522)

#define DATAROW_LENGTH 4

template <size_t T_width>
class DataContainer : public std::array<double, T_width>
{
public:
	DataContainer()
	{
		for (size_t i = 0; i < T_width; ++i)
		{
			this->data()[i] = 0.0;
		}
	}

	void fill(double input)
	{
		for (size_t i = 0; i < T_width; ++i)
		{
			this->data()[i] = input;
		}
	}

	DataContainer Powr(int power)
	{
		for (size_t i = 0; i < T_width; ++i)
		{
			this->data()[i] = pow(this->data()[i], power);
		}
		return *this;
	}

	DataContainer Squrt()
	{
		for (size_t i = 0; i < T_width; ++i)
		{
			this->data()[i] =  std::sqrt(this->data()[i]);
		}
		return *this;
	}

	DataContainer operator-=(const DataContainer& rhs)
	{
		for (size_t i = 0; i < T_width; ++i)
		{
			this->data()[i] -= rhs[i];
		}
		return *this;
	}

	DataContainer& operator+=( DataContainer& rhs)
	{
		DataContainer<T_width> temp;

		for (size_t i = 0; i < T_width; ++i)
		{
			this->data()[i] = this->data()[i] + rhs[i] ;
		}
		return *this;
	}

	void printArray() const
	{
		for (unsigned int i = 0; i < this->size(); i++)
		{
			std::cout << this->data()[i] << std::endl;
		}
	}

	DataContainer operator-(const DataContainer<T_width>& rhs)
	{
		for (size_t i = 0; i < T_width; ++i)
		{
			this->data()[i] -= rhs[i];
		}
		return *this;
	}

	DataContainer<T_width> operator/(int value)
	{
		for (size_t i = 0; i < T_width; ++i)
		{
			this->data()[i] /=  value;
		}
		return *this;
	}

	DataContainer<T_width> operator+(const DataContainer<T_width>& rhs)
	{
		for (size_t i = 0; i <T_width; i++)
		{
			this->data()[i] = this->data()[i] + rhs[i];
		}

		return *this;
	}
};

int main(int argc, char** argv)
{
	typedef DataContainer<DATAROW_LENGTH> DataRow;
	DataRow d1, d2, d3;

	d1.fill(10); 
	std::cout << "AFTER d1 FILL" << std::endl;
	d1.printArray();

	d2.fill(20);
	std::cout << "AFTER d2 FILL" << std::endl;
	d2.printArray();

	d3 = d1 + d2;		// Elementwise addition
	std::cout << "======D3 AFTER d3 = d1+d2" << std::endl;
	d3.printArray();

	d3 = d1 - d2;		// Elementwise subtraction
	std::cout << "===========D3 AFTER d3 = d1-d2" << std::endl;
	d3.printArray();

	d3 = d1 / 5;		// Divide all elements by a constant
	std::cout << "=======D3 AFTER d3 = d1/5" << std::endl;
	d3.printArray();

	std::cout << " =============D1========" << std::endl;
	d1.printArray();

	d3 += d1; 		// Compound assignment
	std::cout << "===============D3 AFTER d3 += d1" << std::endl;
	d3.printArray();

	d3 -= d2;
	std::cout << "===============D3 AFTER d3 -= d2" << std::endl;
	d3.printArray();

	d3 = d1.Powr(2); 	// Raise all elements to a constant power(d1 unchanged)
	std::cout << "===============D3 AFTER d3 = d1.pow(2)" << std::endl;
	d3.printArray();

	d3 = d2.Squrt(); 	// Square root of element (d2 unchanged)
	std::cout << "==============D3 AFTER d3 = d2.sqrt" << std::endl;
	d3.printArray();

	return 0;
}
I see. I fixed the fill function as you suggested and it works. Thanks for all the help.
Topic archived. No new replies allowed.
Pages: 12