I was advised that I should not import the std namespace in a header. Also, I should create my own namespace for my library (a header file I created with function in it).

Why is it a bad idea to use the std namespace for my new functions? If all of my functions have names which are different than the names of std functions, it is no harm, right?

Also, it is more convenient because I won't have to write std::function every time I want to call a function in my program. (Or if my program uses the standard, I would have to use myname::function every time I want to use a function from my header file.)

Recommended Answers

All 16 Replies

Instead of using namespace std; you can using std::cout; and you can now use cout instead of std::cout without pollution the current scope with an entire [unused] namespace.

There are subtle errors that are introduced (especially to the inexperienced) when defaulting to using namespace std; If you are interested in a more detailed explanation, you can follow the link in my signature to my blog and select the 'namespace' tag.

Why is it a bad idea to use the std namespace for my new functions?

If you mean something like this:

namespace std {
   // Add myfunction() to namespace std
   void myfunction();
}

It's a bad idea because doing so invokes undefined behavior. If you mean something else, please clarify.

If all of my functions have names which are different than the names of std functions, it is no harm, right?

Hmm, how do you know all of your names are different? Why even bother cross referencing with the standard (and any other libraries you use) when you could just create a unique namespace and not worry about it?

>>Why is it a bad idea to use the std namespace for my new functions? If all of my functions have names which are different than the names of std functions, it is no harm, right?

No do not do that. To avoid conflicts( perhaps in the future), you should strive for modularity. That is, think of namespace std as a unit which is part of the standard library, and now create your own namespace, and think of that as a different unit thats related to your application, and you may possibly have other namespaces from for example 3rd party library, and so you could think of those namespace as a different unit.


>>Also, it is more convenient because I won't have to write std::function every time I want to call a function in my program. (Or if my program uses the standard, I would have to use myname::function every time I want to use a function from my header file.)

What convenient for you might not be convenient for others. When you program you should program it so that it is easy to maintain. Although it might solve your solution right now, would it cause problems later on the road? Is your solution clear and intuitive?

And whats just one more line to solve your program? Don't be lazy, you can easily say using namespace MyOwnNamespace; and go on from there.

>>Why is it a bad idea to use the std namespace for my new functions?

You should not put anything in the std namespace. There are only very rare (and advanced) reasons to put anything in the std namespace.

And there is nothing special about the std namespace in this regard, the same goes for any library you use. Any good library will have all its things in at least one top-level namespace (like std, boost, cv, etc.), yours should too. Generally, a library is meant to be _used_, meaning that elements of its namespace are invoked (classes and functions). Libraries are rarely meant to be extended by expecting or allowing a user of the library to add things to the library's namespace. The C++ standard library is one such library which is not meant to be "extended" by the user.

You have to understand that entering the namespace of a library is like entering inside the guts of the library, you get exposed to all the complex inner-workings which are fine-tuned to work without your "extensions". And "using namespace .." is like spilling the guts of the library all over the place.

>>If all of my functions have names which are different than the names of std functions, it is no harm, right?

So.. you know all the names of all the functions and classes (including those which are implementation details, like helper functions), and that is, for all implementations of the standard library, for all compilers and all platforms. I doubt that very much. Why take the risk, why bothering yoursefl with this remote chance, just put your own things in your own namespace, avoid the unnecessary risk. Putting things in your own namespace is very liberating, you don't have to come up with complex "unique" names for everything, you just use the simplest most descriptive names, and that is a blessing.

>>Also, it is more convenient because I won't have to write std::function every time I want to call a function in my program. (Or if my program uses the standard, I would have to use myname::function every time I want to use a function from my header file.)

There are two things which are usual, you can use the namespace in source files only and also inside the function bodies. For instance:

#include <iostream>

using namespace std;

int main() {
  cout << "Hello World!" << endl;
  return 0;
};

The above is OK because generally a source file is compiled alone, separate from other source files. And once you have included all the headers you need, they are pollution-free, then, you can import the namespace for the rest of the code in that source file, which will be more convenient (no std:: to type).

In a function body is also a good alternative:

#include <iostream>

void print2();

int main() {
  using namespace std;
  cout << "Hello World!" << endl;
  print2();
  return 0;
};

void print2() {
  cout << "Hello Again!" << endl; //ERROR! the std namespace is only imported for the main() function-body, not for print2().
};

The above is useful if you have a fairly large function (possibly in a header file) which uses many elements of a namespace. You import the namespace, locally for the function only.

But, in general, if you make some use of library elements but not that much, it is not worth importing the namespace. If you are making substantial use of only a few library elements, then you should do the using statement like so:

#include <iostream>

int main() {
  using std::cout; 
  using std::endl;
  cout << "Hello World!" << endl;
  return 0;
};

> when you could just create a unique namespace and not worry about it?
But don't all namespace names occupy the same namespace?

No doubt there is more than one package out there which uses say the 'graphics' namespace. Trying to use two packages with badly chosen generic names could be a challenge.

How do you ensure uniqueness, without a central (cumbersome) registry?

For a small price, I suppose using a namespace derived from a domain name would suffice.

Using UUID's may be unique (and free), but it's cumbersome to write using namespace NS_5798323769944ad3b9c7ca3f5079704b; or NS_5798323769944ad3b9c7ca3f5079704b::myFunction();

>>Trying to use two packages with badly chosen generic names could be a challenge.

I don't think this is really a problem. First of all, most libraries will try to pick a reasonably unique name for the library, and will usually use the same name for the top-level namespace. Second, typically, users of libraries are reasonably aware of the number of external libraries used and which. So, the odds of one project needing two libraries with the same name, same top-level namespace and conflicting elements within that namespace is pretty low. Third, any decent programmer knows how to wrap a (problematic) external library in a thin wrapper with a good compilation firewall (Cheshire Cat). Finally, if all fails, it is always possible to wrap #includes with an additional namespace, it is tricky and not recommended, but a possible last resort. It is also possible to wrap #includes in an unnamed namespace as well.

Using UUIDs for namespace names is a pretty ridiculous solution, no offense.

I appreciate all of your advice. I need an example to truly understand how things should be working. Here is my code conforming to your suggestions. Is it acceptable?

matrixOpsLibrary:

#include <iostream>
#include <vector>
#include <cmath>

namespace matrix{

typedef std::vector<double> Vec; //Vector
typedef std::vector<Vec> Mat; //Matrix


////getColumn////getColumn////getColumn////getColumn////getColumn////getColumn
Vec getCol( Mat x, short b ){ //take's b'th column of x
	Vec y;
	for( short r=0; r<x.size(); ++r ) y.push_back( x[r][b] );
return y;
}
////transpose////'////transpose////'////transpose////'////transpose////'////transpose////'////transpose////'
Mat operator~( Mat x ){ //transpose
	short n = x[0].size();
		Mat trans(n); // transpose
		for( short c=0; c<n; ++c ) trans[c] = getCol( x, c );
return trans;
}
////print////print////print////print////print////print////print////print////print////print////print////print
void printer( double a ){
	std::cout<< "\t<\t" << a << "\t>";
}
void printer( Vec a ){
	std::cout<< "\t<\t";
	for( short i=0; i<a.size(); ++i ) std::cout<< a[i] << '\t';
	std::cout<< '>';
}
void print( Vec a ){
	printer(a);
	std::cout<< "\n\n";
}
void print( Mat a ){
	for( short i=0; i<a.size(); ++i ){ printer(a[i]); std::cout<< '\n'; }
	std::cout<< '\n';
}

} //END NAMESPACE MATRIX

narueReader

#include <fstream>
#include <iterator>
#include <sstream>
#ifndef vector // avoids loading vector again if it has been previously loaded
	#include <vector>
#endif

namespace reader{
using namespace std;

matrix::Mat readMatrix( string filename ){
	matrix::Mat x;

    ifstream in( filename.c_str() );
    if (in) {
        for (string line; getline(in, line);) {
            istringstream iss(line);

            x.push_back(matrix::Vec());
            copy(istream_iterator<double>(iss),
                istream_iterator<double>(),
                back_inserter(x.back()));
        }
    }
return x;
}

} //END READER NAMESPACE

writer

#include <fstream> // not really needed because preloaded in narueReader
#include <sstream> // not really needed because preloaded in narueReader
#include <vector> // not really needed because preloaded in matrixOpsLibrary

namespace writer{
using namespace matrix;
using namespace std;

typedef vector<double> Vec; // not really needed because preloaded in dina
typedef vector<Vec> Mat; // not really needed because preloaded in dina

template <typename T>
std::string to_string(T const& value) {
    stringstream sstr;
    sstr << value;
return sstr.str();
}

string writeVector ( Vec vector ){
	string output; short E = vector.size();
		for( short e=0; e<E-1; ++e ){
			output += " ";
			output += to_string(vector[e]);
			//output += '\t';
		}
	output += " ";
	output += to_string(vector[E-1]);
	output += '\n';
return output;
}

void writeMatrix ( Mat matrix, string filename ){
	string output; short R = matrix.size();
	for( short r=0; r<R; ++r ) output += writeVector( matrix[r] );

	ofstream myfile;
	myfile.open ( filename.c_str() );
		myfile << output;
	myfile.close();
}

} //END WRITER NAMESPACE

myprogram

#include "matrixOpsLibrary.h"
#include "narueReader.h"
#include "writer.h"

using namespace matrix;
using namespace reader;
using namespace writer;

//should we declare globally?
Mat trueA;
Vec C, Nc;
int L;
//END GLOBAL DECLARATIONS

Mat pattern( Mat Q, short K ){
    (this section truncated)
return ~A;
}

Mat dataGen( Mat Q, Mat A, int N, short J, double guess, double mslip, bool link ){
    (this section truncated)
return byElementGreater( pi, ranu(N,J) );
}

void printout( Mat Q, Mat A, Mat X, int N, short J, short K ){
	string tA = "trueA_N"; tA += to_string(N); tA += "_K"; tA += to_string(K); tA += ".dat";
		writeMatrix( trueA, tA );	//cout<< "trueA: ";	print(trueA);
	string x = "X_N"; x += to_string(N); x += "_J"; x += to_string(J); x += "_K"; x += to_string(K); x += ".dat";
		writeMatrix( X, x );	//cout<< "X: ";		print(X);
	cout<< "Latent Classes: " << L << "\n\n";
	cout<< "Q: ";		print(Q);
}

int main(){
	int N=100; short J=30;
	string q="q_J"; q += to_string(J); q += "_K"; q += to_string(K); q += ".txt";

	time_t start = time(&start);
		Mat Q = readMatrix(q);
			/*Vec*/ C = maxc(Q)+1;
			/*int*/ L = prod(C);
		Mat A = pattern( Q, K ); // A is for alpha
		Mat X = dataGen( Q, A, N, J, guess, mslip, link );
	time_t end = time(&end);

	printout( Q, A, X, N, J, K );
	cout<< "Elapsed time of calculation: " << difftime( end, start ) << " seconds" <<endl;
return 0;
}

Line 9 in narueReader should not be there. you never want to include the std namespace into your own namspace. Same goes for writer where you include std and the matrix namespace. you should fully qualify anything used from a seperate namespace in another namespace.

// this can cause problems
namespace foo
{
    using namespace std;   // very bad
    void Print(bar & temp)
    {
        cout << temp;
    }
    //...
}

// this one is fine
namespace foo
{
    void Print(bar & temp)
    {
        std::cout << temp;
    }
    //...
}

Here is a revised version which does not import standard inside any headers. Is this better?

matrixOpsLibrary:

#include <iostream>
#include <vector>
#include <cmath>
 
namespace matrix{
 
typedef std::vector<double> Vec; //Vector
typedef std::vector<Vec> Mat; //Matrix
 
 
////getColumn////getColumn////getColumn////getColumn////getColumn////getColumn
Vec getCol( Mat x, short b ){ //take's b'th column of x
	Vec y;
	for( short r=0; r<x.size(); ++r ) y.push_back( x[r][b] );
return y;
}
////transpose////'////transpose////'////transpose////'////transpose////'////transpose////'////transpose////'
Mat operator~( Mat x ){ //transpose
	short n = x[0].size();
		Mat trans(n); // transpose
		for( short c=0; c<n; ++c ) trans[c] = getCol( x, c );
return trans;
}
////print////print////print////print////print////print////print////print////print////print////print////print
void printer( double a ){
	std::cout<< "\t<\t" << a << "\t>";
}
void printer( Vec a ){
	std::cout<< "\t<\t";
	for( short i=0; i<a.size(); ++i ) std::cout<< a[i] << '\t';
	std::cout<< '>';
}
void print( Vec a ){
	printer(a);
	std::cout<< "\n\n";
}
void print( Mat a ){
	for( short i=0; i<a.size(); ++i ){ printer(a[i]); std::cout<< '\n'; }
	std::cout<< '\n';
}
 
} //END NAMESPACE MATRIX

narueReader

#include <fstream>
#include <iterator>
#include <sstream>
#ifndef vector // avoids loading vector again if it has been previously loaded
	#include <vector>
#endif
 
namespace reader{
 
matrix::Mat readMatrix( std::string filename ){
	matrix::Mat x;

    std::ifstream in( filename.c_str() );
    if (in) {
        for (std::string line; getline(in, line);) {
            std::istringstream iss(line);

            x.push_back(matrix::Vec());
            copy(std::istream_iterator<double>(iss),
                std::istream_iterator<double>(),
                back_inserter(x.back()));
        }
    }
return x;
}

} //END READER NAMESPACE

writer

#include <fstream> // not really needed because preloaded in narueReader
#include <sstream> // not really needed because preloaded in narueReader
#include <vector> // not really needed because preloaded in matrixOpsLibrary
 
namespace writer{
using namespace matrix;
using std::string;

typedef std::vector<double> Vec; // not really needed because preloaded in dina
typedef std::vector<Vec> Mat; // not really needed because preloaded in dina

template <typename T>
string to_string(T const& value) {
    std::stringstream sstr;
    sstr << value;
return sstr.str();
}

string writeVector ( Vec vector ){
	string output; short E = vector.size();
		for( short e=0; e<E-1; ++e ){
			output += " ";
			output += to_string(vector[e]);
			//output += '\t';
		}
	output += " ";
	output += to_string(vector[E-1]);
	output += '\n';
return output;
}

void writeMatrix ( Mat matrix, string filename ){
	string output; short R = matrix.size();
	for( short r=0; r<R; ++r ) output += writeVector( matrix[r] );

	std::ofstream myfile;
	myfile.open ( filename.c_str() );
		myfile << output;
	myfile.close();
}

} //END WRITER NAMESPACE

myprogram

#include "matrixOpsLibrary.h"
#include "narueReader.h"
#include "writer.h"
 
using namespace matrix;
using namespace reader;
using namespace writer;
using std::cout;
using std::endl;
 
//should we declare globally?
Mat trueA;
Vec C, Nc;
int L;
//END GLOBAL DECLARATIONS
 
Mat pattern( Mat Q, short K ){
    (this section truncated)
return ~A;
}
 
Mat dataGen( Mat Q, Mat A, int N, short J, double guess, double mslip, bool link ){
    (this section truncated)
return byElementGreater( pi, ranu(N,J) );
}
 
void printout( Mat Q, Mat A, Mat X, int N, short J, short K ){
	string tA = "trueA_N"; tA += to_string(N); tA += "_K"; tA += to_string(K); tA += ".dat";
		writeMatrix( trueA, tA );	//cout<< "trueA: ";	print(trueA);
	string x = "X_N"; x += to_string(N); x += "_J"; x += to_string(J); x += "_K"; x += to_string(K); x += ".dat";
		writeMatrix( X, x );	//cout<< "X: ";		print(X);
	cout<< "Latent Classes: " << L << "\n\n";
	cout<< "Q: ";		print(Q);
}
 
int main(){
	int N=100; short J=30;
	string q="q_J"; q += to_string(J); q += "_K"; q += to_string(K); q += ".txt";
 
	time_t start = time(&start);
		Mat Q = readMatrix(q);
			/*Vec*/ C = maxc(Q)+1;
			/*int*/ L = prod(C);
		Mat A = pattern( Q, K ); // A is for alpha
		Mat X = dataGen( Q, A, N, J, guess, mslip, link );
	time_t end = time(&end);
 
	printout( Q, A, X, N, J, K );
	cout<< "Elapsed time of calculation: " << difftime( end, start ) << " seconds" <<endl;
return 0;
}

I'm pretty sure I've got the right code here. If someone could just verify that I'm doing things in a good way that would be great. It's really NOT a long code to muddle through. It's just the headers and namespaces you have to look at.

Thanks!

Just some few points:

typedef std::vector<double> Vec; //Vector
typedef std::vector<Vec> Mat; //Matrix

Its just preference, but I think its more clearer if you say the full Name, maybe

typedef std::vector<double> RowVector;
typedef std::vector<RowVector> Matrix;

Use const-correctness when you can, for example:

////getColumn////getColumn////getColumn////getColumn////getColumn////getColumn
Vec getCol( Mat x, short b ){ //take's b'th column of x
    Vec y;
    for( short r=0; r<x.size(); ++r ) y.push_back( x[r][b] );
return y;
}

that function doesn't modify matrix x, so make it const Mat& x, remember to use reference when you can so you avoid making unnecessary copies. And there is no advantage of using short, just use int because the compiler might turn it into an int anways. Plus it feels like more convention to use int in loops rather than shorts, not to mention int's range is higher. So the resulting code might look like this:

Vec getColumn(const Mat& matrix,const int columnNumber){ 
 Vec columnVector(matrix.size()); //initialize its size to the amount of row
 for(unsigned row = 0; row < matrix.size(); ++row){
    columnVector[row] = matrix[row][columnNumber];
 }
 return columnVector;
}

In matrix and vector operations, people have all kinds of crazy operators that do different things, and in turn this makes it harder for the users. So Instead of defining a weird operator that isn't really standard, in terms of its use, just create a named function. For example you have,

////transpose////'////transpose////'////transpose////'////transpose////'////transpose////'////transpose////'
Mat operator~( Mat x ){ //transpose
    short n = x[0].size();
        Mat trans(n); // transpose
        for( short c=0; c<n; ++c ) trans[c] = getCol( x, c );
return trans;
}

Me as a users would have better time understanding and using that function if it was named properly, for example,

Mat transpose(const Mat& maxtrix ){ 
 unsigned colSize = matrix[0].size(); //note assumes square matrix!!
 Mat transposdMatrix(colSize);
 for( unsigned col = 0; col < colSize; ++col ){
   transposedMatrix[c] = getCol( matrix, col );
 }
 return trans;
}

There is no reason to sacrifice clarity in the above function. Instead of naming a matrix x, name it matrix!.

This

#ifndef vector // avoids loading vector again if it has been previously loaded
 #include <vector>
#endif

There is no point in doing this. The compiler will not and cannot load a the vector library twice. If you have say two #include<vector> statement in one file, then the compiler will just load in the vector library once. Since the library are dll's that means all application share just one instance of that library instead of creating a instance for each application, thus the term dynamic linked libraries.
So just remove that.

And now we're off the the reader namespace. Why exactly are you creating a different namespace for each types of functions? The point of namespace if to avoid name collision. So although creating a namespace for each types of category isn't really really bad, it does make it harder for the user to use. Just have all operations that are related to matrix class in the same namespace, although they can be defined in different files.

This code:

matrix::Mat readMatrix( std::string filename ){

You should know that most code I have seen on the web, in forumn, and at my internships have a customary to defined classes with a capital letter first. So instead of calling the class matrix they would call it Matrix. So why not follow the convention? This way, it makes it easier for readers of future maintainers to follow your code. And dont't forget about constant references! So the resulting code might look something like this

Matrix::MatrixType readMatrix(const std::string& filename )const{ ... }

Also since this is a member function and its not altering the member variables, you can and should append the extra const after the function parameters.

Now this code:

namespace writer{
using namespace matrix;
using std::string; 
typedef std::vector<double> Vec; // not really needed because preloaded in dina
typedef std::vector<Vec> Mat; // not really needed because preloaded in dina

Since you already made a typedef in matrix namespace, why not make use of it like so:

namespace writer{
using namespace matrix;
using std::string;

typedef matrix::Vec Vec; // not really needed because preloaded in dina
typedef matrix::Mat Mat; // not really needed because preloaded in dina

but that still isn't really needed since you load in the whole matrix namespace so you can just delete it.

And this:

//should we declare globally?
Mat trueA;
Vec C, Nc;
int L;
//END GLOBAL DECLARATIONS

The answer is NO. In general strive for not creating global variables. For example this,

#include <iostream>
int n = 0;
void printN(){ std::cout << n << "\n"; }
int main(){
 printN();
}

should be this:

#include <iostream>
void printN(const int n){ std::cout << n << "\n"; }
int main(){
 int n = 0;
 printN(n);
}

so look for a way to pass a reference instead of making it global. And Try not to sacrifice clarity. Make your function names clear, the code clear, and avoid making copies when you can pass a constant reference.

You have a weird way to implement our suggestions.

First of all, you need header-guards. This is important to ensure that the same code does not appear twice, because if the compiler looks at the same code twice it will not like it, as it breaks a fundamental rule of C/C++, that is, the One Definition Rule (ODR), which states that you should not define something with the same name twice (type or function or variable or whatever), even if the definition is the same.

For some reason, you put this:

#ifndef vector // avoids loading vector again if it has been previously loaded

I guess the intent was to not #include <vector> twice. Not only is that unnecessary because the <vector> header, like any other header in any other library that is worthy to be used by anyone, has a header-guard, so double-inclusion is not a problem to be worried about, ever (as long as all headers that you create or use have a header-guard, which is pretty much a given in C/C++). Second problem with the above statement, is that it will #include <vector> after this line, no matter what. All directives that start with # symbol are pre-processor directives, meaning that they are processed before the (real) compiler looks at the code. The pre-processor basically ignores everything else and just processes the # directives (except that it also does a find-and-replace through the code for all the #define identifiers, like "#define X Y" will cause all occurrences of X to be replaced by Y). This means that "vector" is meaningless to the pre-processor (either as the name of the header file <vector> or as the name of the class std::vector), so it will always see "vector" as undefined.

And @firstPerson, <vector> is a header-only template library, why you bring up the aspect of loading DLLs beats me. This is just a question of include-guards (or header-guards). If you have #include <vector> twice, the only thing that is going to happen at the second #include statement is that the pre-processor will re-open the <vector> header-file, see the include-guard, skip to the end, and no code will be added as a consequence.


Now, to the core of it, your namespace usage. I guess you didn't notice when I said:
"First of all, most libraries will try to pick a reasonably unique name for the library, and will usually use the same name for the top-level namespace."
In response to the problem of "Trying to use two packages with badly chosen generic names could be a challenge.".
So, you picked the names "matrix", "reader" and "writer" for your namespaces... I couldn't have imagined an example of more generic and badly chosen names for top-level namespaces.

If you are really going to make any kind of a library, you want to pick a name for it, keep it short, catchy, and unique! For example, my library is called ReaK, which is pretty short, catchy and unique, but it doesn't really mean anything, or at least, I forgot what it meant, it doesn't matter much. The point is, you want to put all your library code under one top-level namespace with a short and unique name (at least unique enough that you would expect there to be conflicts). "matrix" for instance is as far from unique as you can get, there are a ton of C++ libraries that would contain things called matrix or something close to that.

Then, the way you organized your namespaces is unusual at best. First, you don't need to fine-grain it like that. You have a ratio of about 1 namespace for about 4-5 functions (or elements), a more normal ratio is about 1 namespace for 200-300 elements (including functions, types, classes, etc.). Second, it is generally good practice to group data-structures and their related functions in the same namespace, don't put class or type definitions in one namespace and free-functions which are strongly related to those types into another namespace, that's bad, and it can have bad consequences too. Any function that is directly depend on a given type or class, should be in the same namespace as that type or class. Of course, if you have functions which deal with types that are in separate namespaces, then either rethink if they might be better grouped together in one namespace or choose to put the function in either namespace where it makes more conceptual sense.


On a final note, as firstPerson pointed out, you should pass matrices and vectors by const-reference or reference in the functions you have there, avoid the unnecessary copies and temporaries.

Oh, and the "convention" that firstPerson mentioned is one option, it is more popular in Java, and is somewhat out-of-trend in C++, but it is used a lot nonetheless. Another popular convention is that of STL and Boost, which is more oriented towards heavily templated code, most modern libraries follow that convention (mostly because modern C++ programmers are well versed in the STL and Boost, as well as templates, it is a natural convention to use). But, the point is that you need to choose a convention and stick to it. It is not so important what conventions you use, believe me, experienced programmers have seen them all and can adapt to any, but consistency is the key.

>>And @firstPerson, <vector> is a header-only template library, why you bring up the aspect of loading DLLs beats me. This is just a question of include-guards (or header-guards). If you have #include <vector> twice, the only thing that is going to happen at the second #include statement is that the pre-processor will re-open the <vector> header-file, see the include-guard, skip to the end, and no code will be added as a consequence.

Oh ok. I was thinking something else.

that function doesn't modify matrix x, so make it const Mat& x, remember to use reference when you can so you avoid making unnecessary copies. And there is no *advantage* of using short, just use int because the compiler might turn it into an int anyways.

This brings up two questions. Firstly, you say short has no *advantage* over int. Following the same logic, does unsigned have no *advantage* over int either? The reason I ask is because I see you are using unsigned in your example. I was going to switch over most of my code to unsigned and ints, but it will take a while for me to do. It would be much easier to switch over to all int's.

But it is definitely worth using unsigned for me if there is a speed advantage. My code needs to be as efficient as possible.


Second question: I see you are suggesting the use of function( const Mat& x )

I now understand that I should use const if the value of x is not going to change in the function. But why the & symbol? I thought the & symbol was for when you DO want to change the value of x, not just in the function but in the entire program. Perhaps I'm confused.

The ampersand & when appended to a type-name marks it as a reference. So, this type const Matrix& reads as "a reference to a constant Matrix", while Matrix& reads as "a reference to a Matrix", and Matrix is, of course, just a Matrix. If you pass a variable as Matrix , it is passed-by-value, meaning that the parameter will, in theory at least, be copied before the code enters the function. If the & is used, then you pass-by-reference, meaning that a reference is taken from the parameter (i.e. its address is taken) and passed to the function, it means that you don't cause a copy. If you have a parameter that is strictly an input parameter (you only need to read data from the parameter), and it is not cheap to copy it, then you can pass it by const-reference meaning that you don't copy the parameter, just pass a reference to it, but since you mark it as "const" you force yourself not to modify it and you also promise the caller of the function that his variable will not get modified during the function execution. If you want an input/output parameter, then, pass by reference (non-const). And passing as const Matrix (by value, but const) is not any better performance-wise than passing by non-const value.

foo(Matrix m); //makes a copy
foo(Matrix& m); //does not create a copy but now we are able to change m inside foo
foo(const Matrix m); //makes a copy, not allowed to change inside foo
foo(const Matrix& m); //does not create a copy and cannot change m inside foo

and no noticible performance boost from unsigned versus int. I just hate getting those "Warning: comparing signed and unsigned", so I just make the variable in the loop unsigned by default. If the variable doesn't need to be negative, then just make it unsigned. But making it int is no problem either, in most cases.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.