I've been coding in C# for quite a while now and have switched back to C++ recently. Basically what I'm trying to do in terms of C# is:
static void Main(string[] args)
{
int[,] mat = { {1, 2, 3},
{4, 5, 6},
{7, 8, 9} };
SomeClass<int> s1 = new SomeClass<int>(mat);
int[,] result = s1.doSomething();
int[,] mat2 = { { 1, 2, 3, 4},
{ 5, 6, 7, 8},
{ 9, 10, 11, 12},
{13, 14, 15, 16} };
SomeClass<int> s2 = new SomeClass<int>(mat);
int[,] result2 = s2.doSomething();
}
public class SomeClass<T>
{
T[,] data;
public SomeClass(T[,] arg)
{
data = arg;
}
//member method of SomeClass
public T[,] doSomething()
{
return data;
}
}
Actually this shouldn't be to hard at the first glance but unfortunately C++
is a bit more picky when it comes to arrays of anonymous size. There are some
workarounds of course:
Use T**
I consider this solution quite hacky, T** is not really the same as T[][] and
you can pass messy things that might result into runtime errors rather than
compiler errors. Then there is the initialization issue.
T[][]
Would be nice but unlike C# C++ doesn't allow the declaration of 2D arrays of
anonymous size in both dimensions (T[][3]) would be possible but none of the
two dimensions should be fixed. I need to be able to work with 3x3 matrices at
one point in the program and lets say with 4x4 or 5x5 matrices at another point.
So I did some research and found another approach using templates and non-type
parameters. So my idea is to do sth. like this:
template<typename T, size_t S>
Someclass<T, S>::Someclass(T[S][S]) { .. }
template<typename T, size_t S>
T[S][S] Someclass<T, S>:doSomething() { .. }
.. which unfortunately doesn't seem to work that way. This approach has even one
more advantage it implicitly adds a constraint that the first and the second
dimension of the array must be of the same size.
I'm using Visual Studio 2010's compiler so I might not be able to use the
features of the latest C++ compilers.
So my question: Is there a way to achive what the 3rd idea implies?
- Pass and return 2D Arrays of anonymous size...
- ...with the constraint that the first and second dimension must be of the
same size.
** UPDATE **
I've been having a hard time getting the proposed solutions to run under Visual Studio. I'll give it another try but wanted to keep you posted:
I created a small test Project - this is how far I got:
//SomeClass.h
#ifndef SOMECLASS_H //<- line 1
#define SOMECLASS_H
#include "SquareMatrixA.h"
#include "SquareMatrixB.h"
template<typename T, size_t S>
class SomeClass
{
private:
SquareMatrixA<T> matA;
SquareMatrixB<T, S> matB;
public:
SomeClass(SquareMatrixA<T> arg);
SomeClass(SquareMatrixB<T, S> arg);
virtual ~SomeClass(void);
SquareMatrixA<T> doSomethingA();
SquareMatrixB<T, S> doSomethingB();
};
#endif
//SomeClass.cpp //<-- line 1
#include "SomeClass.h"
template<typename T, size_t S>
SomeClass<T, S>::SomeClass(SquareMatrixA<T> arg) { matA = arg; }
template<typename T, size_t S>
SomeClass<T, S>::SomeClass(SquareMatrixB<T, S> arg) { matB = arg; }
template<typename T, size_t S>
SomeClass<T, S>::~SomeClass(){}
template<typename T, size_t S>
SquareMatrixA<T> SomeClass<T, S>::doSomethingA() { return matA; }
template<typename T, size_t S>
SquareMatrixB<T, S> SomeClass<T, S>::doSomethingB() { return matB; }
//SquareMatrixA.h (inline)
#ifndef SQUAREMATRIXA_H //<- line 1
#define SQUAREMATRIXA_H
#include <vector>
#include <utility>
template<typename T>
class SquareMatrixA
{
protected:
std::vector<T> data;
size_t size;
public:
SquareMatrixA(size_t size) : data(size * size), size(size) { }
T& operator()(size_t i, size_t j) { return data.at(i * size + j); }
T const& operator() const(size_t i, size_t j) { return data.at(i * size + j); }
T& operator[](std::pair<size_t, size_t> p) { return data.at(p.first * size + p.second); }
T const& operator[](std::pair<size_t, size_t> p) const { return data.at(p.first * size + p.second); }
};
#endif
//SquareMatrixB.h
#ifndef SQUAREMATRIXB_H // <-- line
#define SQUAREMATRIXB_H
template<typename T, size_t S>
class SquareMatrixB
{
typedef T (&oneDimRefT)[S];
private:
T matrix[S][S];
public:
const size_t Size;
SquareMatrixB(size_t sizeA) : Size(sizeA) { }
oneDimRefT operator[](size_t i) { return matrix[i]; }
};
#endif
Visual Studio shows the following errors (sorry for the partially german output
but seemingly Visual Studios language cant changed to english except by
installing a native english Version:
Fehler 1 error C2143: Syntaxfehler: Es fehlt ';' vor 'const' squarematrixa.h 17 1 MatrixTest2
Fehler 2 error C2365: "SquareMatrixA<T>::operator ()": Erneute Definition; vorherige Definition war "Memberfunktion". squarematrixa.h 17 1 MatrixTest2
Fehler 3 error C4430: Fehlender Typspezifizierer - int wird angenommen. Hinweis: "default-int" wird von C++ nicht unterstützt. squarematrixa.h 17 1 MatrixTest2
Fehler 4 error C2226: Syntaxfehler: Typ 'size_t' nicht erwartet squarematrixa.h 17 1 MatrixTest2
Fehler 5 error C2334: Unerwartete(s) Token vor '{'; sichtbarer Funktionstext wird übersprungen squarematrixa.h 17 1 MatrixTest2