vector and Template confusion
-
I will start with my code:
template < typename T1, typename T2 >
void printvector(T1& fout, const std::vector < T2 >& V)
{
if (V.empty()) fout << "EMPTY\n";
else {
for (size_t x = 0; x != V.size() - 1; ++x)
{
<< ", ";
}
fout << V[V.size() - 1] << '\n';
}
}fstream StatFile;
StatFile.open(STATICFILE, std::fstream::out);
if (StatFile.is_open())
{
for (i = 0; i != NewLandmarks.size(); ++i)
{
cout << NewLandmarks[i].name << " "; printvector(cout, Subtractions);
StatFile << NewLandmarks[i].fiducial << ", " << NewLandmarks[i].name << ", "; NewLandmarks[i].location.print(StatFile);
if (Subtractions.empty()) StatFile << "\n";
else {
StatFile << ','; printvector(StatFile, Subtractions);
}
}
StatFile.close();
}The template is supposed to print out the contents of a vector, either to the console when given cout, or to a text file when given an fstream variable. NewLandmarks is a vector of a struct and that seems to be working just fine here. Subtractions is a vector of size_t, and this is where the problem lies. When the code runs, the NewLandmarks name is printed to the console, as well as the contents of the Subtractions vector, which in this case is always 45, 46, 47, 48 When the code gets to the next line, where it prints to the file, NewLandmarks.fiducial, NewLandmarks.name and NewLandmarks.location.print(StatFile) all work as expected. However, the Subtractions vector only prints its last element, 48, to the file. This implies that the Subtractions vector somehow got changed by the printvector template. But, I don't see how, or why. Even more confusing, this code loops several times. The first time Subtractions prints to the file as 48. The second time it prints as 47, 48. The third time as 46, 47, 48. I don't loop through a fourth time, but I think I can see what would happen. But I still don't know why. Even worse, during each of these loops when Subtractions is printed to the console I always get the full vector: 45, 46, 47, 48. So, Why is the template function behaving differently from its console and file printing activations? Why does the template function write only the last element of the vector to the file and its first iteration? Why does the template function change behavior and write an additional vector element each time it
-
I will start with my code:
template < typename T1, typename T2 >
void printvector(T1& fout, const std::vector < T2 >& V)
{
if (V.empty()) fout << "EMPTY\n";
else {
for (size_t x = 0; x != V.size() - 1; ++x)
{
<< ", ";
}
fout << V[V.size() - 1] << '\n';
}
}fstream StatFile;
StatFile.open(STATICFILE, std::fstream::out);
if (StatFile.is_open())
{
for (i = 0; i != NewLandmarks.size(); ++i)
{
cout << NewLandmarks[i].name << " "; printvector(cout, Subtractions);
StatFile << NewLandmarks[i].fiducial << ", " << NewLandmarks[i].name << ", "; NewLandmarks[i].location.print(StatFile);
if (Subtractions.empty()) StatFile << "\n";
else {
StatFile << ','; printvector(StatFile, Subtractions);
}
}
StatFile.close();
}The template is supposed to print out the contents of a vector, either to the console when given cout, or to a text file when given an fstream variable. NewLandmarks is a vector of a struct and that seems to be working just fine here. Subtractions is a vector of size_t, and this is where the problem lies. When the code runs, the NewLandmarks name is printed to the console, as well as the contents of the Subtractions vector, which in this case is always 45, 46, 47, 48 When the code gets to the next line, where it prints to the file, NewLandmarks.fiducial, NewLandmarks.name and NewLandmarks.location.print(StatFile) all work as expected. However, the Subtractions vector only prints its last element, 48, to the file. This implies that the Subtractions vector somehow got changed by the printvector template. But, I don't see how, or why. Even more confusing, this code loops several times. The first time Subtractions prints to the file as 48. The second time it prints as 47, 48. The third time as 46, 47, 48. I don't loop through a fourth time, but I think I can see what would happen. But I still don't know why. Even worse, during each of these loops when Subtractions is printed to the console I always get the full vector: 45, 46, 47, 48. So, Why is the template function behaving differently from its console and file printing activations? Why does the template function write only the last element of the vector to the file and its first iteration? Why does the template function change behavior and write an additional vector element each time it
Did you debug your code?
-
Did you debug your code?
Yes, or that is what I am in the process of doing. I found this unexpected behavior and I do not know why it happens or how to fix it.
-
I will start with my code:
template < typename T1, typename T2 >
void printvector(T1& fout, const std::vector < T2 >& V)
{
if (V.empty()) fout << "EMPTY\n";
else {
for (size_t x = 0; x != V.size() - 1; ++x)
{
<< ", ";
}
fout << V[V.size() - 1] << '\n';
}
}fstream StatFile;
StatFile.open(STATICFILE, std::fstream::out);
if (StatFile.is_open())
{
for (i = 0; i != NewLandmarks.size(); ++i)
{
cout << NewLandmarks[i].name << " "; printvector(cout, Subtractions);
StatFile << NewLandmarks[i].fiducial << ", " << NewLandmarks[i].name << ", "; NewLandmarks[i].location.print(StatFile);
if (Subtractions.empty()) StatFile << "\n";
else {
StatFile << ','; printvector(StatFile, Subtractions);
}
}
StatFile.close();
}The template is supposed to print out the contents of a vector, either to the console when given cout, or to a text file when given an fstream variable. NewLandmarks is a vector of a struct and that seems to be working just fine here. Subtractions is a vector of size_t, and this is where the problem lies. When the code runs, the NewLandmarks name is printed to the console, as well as the contents of the Subtractions vector, which in this case is always 45, 46, 47, 48 When the code gets to the next line, where it prints to the file, NewLandmarks.fiducial, NewLandmarks.name and NewLandmarks.location.print(StatFile) all work as expected. However, the Subtractions vector only prints its last element, 48, to the file. This implies that the Subtractions vector somehow got changed by the printvector template. But, I don't see how, or why. Even more confusing, this code loops several times. The first time Subtractions prints to the file as 48. The second time it prints as 47, 48. The third time as 46, 47, 48. I don't loop through a fourth time, but I think I can see what would happen. But I still don't know why. Even worse, during each of these loops when Subtractions is printed to the console I always get the full vector: 45, 46, 47, 48. So, Why is the template function behaving differently from its console and file printing activations? Why does the template function write only the last element of the vector to the file and its first iteration? Why does the template function change behavior and write an additional vector element each time it
Probably there is part of your code (not posted here) messing up with the
Subtraction
vector. This code#include #include #include using namespace std;
template < typename T1, typename T2 >
void printvector(T1& fout, const std::vector < T2 >& V)
{
if (V.empty()) fout << "EMPTY\n";
else {
for (size_t x = 0; x != V.size() - 1; ++x)
{
<< ", ";
}
fout << V[V.size() - 1] << '\n';
}
}int main()
{
vector sub {46,47,48};printvector(cout, sub);
fstream foofile("foo.txt", ios::out);
if (foofile)
{
printvector(foofile, sub);
}
}produces the same output
46, 47, 48
both to the console and to the
foo.txt
file. [update] Note, you might also write#include
#include
#include
using namespace std;template
ostream & operator<< (ostream & os, const vector & v)
{
if ( v.empty() ) os << "EMPTY\n";
else
{
for (size_t n = 0; n != v.size() - 1; ++n)
{
os << v[n] << ", ";
}
os << v.back() << '\n';
}
return os;
}int main()
{
vector sub {46,47,48};cout << sub;
fstream foofile("foo.txt", ios::out);
if (foofile)
{
foofile << sub;
}
}[/update]
"In testa che avete, Signor di Ceprano?" -- Rigoletto
-
I will start with my code:
template < typename T1, typename T2 >
void printvector(T1& fout, const std::vector < T2 >& V)
{
if (V.empty()) fout << "EMPTY\n";
else {
for (size_t x = 0; x != V.size() - 1; ++x)
{
<< ", ";
}
fout << V[V.size() - 1] << '\n';
}
}fstream StatFile;
StatFile.open(STATICFILE, std::fstream::out);
if (StatFile.is_open())
{
for (i = 0; i != NewLandmarks.size(); ++i)
{
cout << NewLandmarks[i].name << " "; printvector(cout, Subtractions);
StatFile << NewLandmarks[i].fiducial << ", " << NewLandmarks[i].name << ", "; NewLandmarks[i].location.print(StatFile);
if (Subtractions.empty()) StatFile << "\n";
else {
StatFile << ','; printvector(StatFile, Subtractions);
}
}
StatFile.close();
}The template is supposed to print out the contents of a vector, either to the console when given cout, or to a text file when given an fstream variable. NewLandmarks is a vector of a struct and that seems to be working just fine here. Subtractions is a vector of size_t, and this is where the problem lies. When the code runs, the NewLandmarks name is printed to the console, as well as the contents of the Subtractions vector, which in this case is always 45, 46, 47, 48 When the code gets to the next line, where it prints to the file, NewLandmarks.fiducial, NewLandmarks.name and NewLandmarks.location.print(StatFile) all work as expected. However, the Subtractions vector only prints its last element, 48, to the file. This implies that the Subtractions vector somehow got changed by the printvector template. But, I don't see how, or why. Even more confusing, this code loops several times. The first time Subtractions prints to the file as 48. The second time it prints as 47, 48. The third time as 46, 47, 48. I don't loop through a fourth time, but I think I can see what would happen. But I still don't know why. Even worse, during each of these loops when Subtractions is printed to the console I always get the full vector: 45, 46, 47, 48. So, Why is the template function behaving differently from its console and file printing activations? Why does the template function write only the last element of the vector to the file and its first iteration? Why does the template function change behavior and write an additional vector element each time it
-
Probably there is part of your code (not posted here) messing up with the
Subtraction
vector. This code#include #include #include using namespace std;
template < typename T1, typename T2 >
void printvector(T1& fout, const std::vector < T2 >& V)
{
if (V.empty()) fout << "EMPTY\n";
else {
for (size_t x = 0; x != V.size() - 1; ++x)
{
<< ", ";
}
fout << V[V.size() - 1] << '\n';
}
}int main()
{
vector sub {46,47,48};printvector(cout, sub);
fstream foofile("foo.txt", ios::out);
if (foofile)
{
printvector(foofile, sub);
}
}produces the same output
46, 47, 48
both to the console and to the
foo.txt
file. [update] Note, you might also write#include
#include
#include
using namespace std;template
ostream & operator<< (ostream & os, const vector & v)
{
if ( v.empty() ) os << "EMPTY\n";
else
{
for (size_t n = 0; n != v.size() - 1; ++n)
{
os << v[n] << ", ";
}
os << v.back() << '\n';
}
return os;
}int main()
{
vector sub {46,47,48};cout << sub;
fstream foofile("foo.txt", ios::out);
if (foofile)
{
foofile << sub;
}
}[/update]
"In testa che avete, Signor di Ceprano?" -- Rigoletto
That is what I thought at first. But why does the vector print correctly when it is to the console and incorrectly when it is to a file, and the two commands are right next to each other. Where was the opportunity to screw up the Subtractions vector?
-
I just ran the above code and it works correctly. I had to create my own version of the NewLandmarks structure, so maybe what you have is actually the issue.
Here is my struct and the NewLandmarks vector. Do you see anything in this code that could be causing this problem?
struct landmarktype {
std::string fiducial{};
std::string name{};
Matrix location{}; //=Initialize(3,1);
std::vector subtractions{};
};vector NewLandmarks;
declared earlier in the code, but in case it's important here is my Matrix class:
class Matrix {
private:
double * M;
size_t ROWS, COLUMNS;
public:
Matrix(): M(NEW double[1]), ROWS(1), COLUMNS(1) {} // default constructor
Matrix(size_t R, size_t C): M(NEW double[R * C]), ROWS(R), COLUMNS(C) {} // constructor
~Matrix() {delete[] M;}; // destructor
Matrix(const Matrix & m): M(NEW double[m.ROWS * m.COLUMNS]), // copy constructor
ROWS(m.ROWS), COLUMNS(m.COLUMNS) {
for (size_t i = 0; i != (ROWS * COLUMNS); i++) M[i] = m.M[i];
}double & operator()(const size\_t R, const size\_t C); //output a value from (row,col) cell double operator()(const size\_t R, const size\_t C) const; \[\[nodiscard\]\] size\_t rows() const { return ROWS; } \[\[nodiscard\]\] size\_t cols() const { return COLUMNS; } void set(const size\_t R, const size\_t C) { double\* newMat = NEW double\[R\*C\]; delete\[\] M; M = newMat; ROWS = R; COLUMNS = C; } void clear() { double\* newMat = DBG\_NEW double\[0\]; delete\[\] M; M = newMat; ROWS = 0; COLUMNS = 0; } void print(std::fstream & ) const;
}
void Matrix::print(fstream & fout) const {
size_t r, c;
for (c = 0; c != COLUMNS; ++c)
for (r = 0; r != ROWS; ++r)
{
fout << setiosflags(ios::fixed) << std::setprecision(outputprecision) << std::setw(22) << M[r * COLUMNS + c];
if ((r*COLUMNS+c) != (ROWS*COLUMNS - 1)) fout << ", ";
}
} -
Here is my struct and the NewLandmarks vector. Do you see anything in this code that could be causing this problem?
struct landmarktype {
std::string fiducial{};
std::string name{};
Matrix location{}; //=Initialize(3,1);
std::vector subtractions{};
};vector NewLandmarks;
declared earlier in the code, but in case it's important here is my Matrix class:
class Matrix {
private:
double * M;
size_t ROWS, COLUMNS;
public:
Matrix(): M(NEW double[1]), ROWS(1), COLUMNS(1) {} // default constructor
Matrix(size_t R, size_t C): M(NEW double[R * C]), ROWS(R), COLUMNS(C) {} // constructor
~Matrix() {delete[] M;}; // destructor
Matrix(const Matrix & m): M(NEW double[m.ROWS * m.COLUMNS]), // copy constructor
ROWS(m.ROWS), COLUMNS(m.COLUMNS) {
for (size_t i = 0; i != (ROWS * COLUMNS); i++) M[i] = m.M[i];
}double & operator()(const size\_t R, const size\_t C); //output a value from (row,col) cell double operator()(const size\_t R, const size\_t C) const; \[\[nodiscard\]\] size\_t rows() const { return ROWS; } \[\[nodiscard\]\] size\_t cols() const { return COLUMNS; } void set(const size\_t R, const size\_t C) { double\* newMat = NEW double\[R\*C\]; delete\[\] M; M = newMat; ROWS = R; COLUMNS = C; } void clear() { double\* newMat = DBG\_NEW double\[0\]; delete\[\] M; M = newMat; ROWS = 0; COLUMNS = 0; } void print(std::fstream & ) const;
}
void Matrix::print(fstream & fout) const {
size_t r, c;
for (c = 0; c != COLUMNS; ++c)
for (r = 0; r != ROWS; ++r)
{
fout << setiosflags(ios::fixed) << std::setprecision(outputprecision) << std::setw(22) << M[r * COLUMNS + c];
if ((r*COLUMNS+c) != (ROWS*COLUMNS - 1)) fout << ", ";
}
}I cannot get that to build, the compiler does not know
NEW
orDBG_NEW
. But either way that is a rather complex class. However, I can see nothing obvious, I guess the only way to find the problem is via the debugger. [edit] OK, with a bit of editing I got it to work and the output is correct (as far as I can see) in both cases. So the issue must have something to do with what you are running, or your data. [/edit] -
I cannot get that to build, the compiler does not know
NEW
orDBG_NEW
. But either way that is a rather complex class. However, I can see nothing obvious, I guess the only way to find the problem is via the debugger. [edit] OK, with a bit of editing I got it to work and the output is correct (as far as I can see) in both cases. So the issue must have something to do with what you are running, or your data. [/edit]Sorry, my mistake. That's my attempt at some debugging. When I switch debugging off the preprocessor will replace NEW and DBG_NEW with new. Do that now and it should compile.
-
Sorry, my mistake. That's my attempt at some debugging. When I switch debugging off the preprocessor will replace NEW and DBG_NEW with new. Do that now and it should compile.
-
That is what I thought at first. But why does the vector print correctly when it is to the console and incorrectly when it is to a file, and the two commands are right next to each other. Where was the opportunity to screw up the Subtractions vector?