Moderator edit: This response and its replies have been split from the C and C++ Timesaving Tips sticky because they do not add relevant material, and they are long enough to distract from the intended purpose of the thread. Further replies on this topic may be posted in this thread, while other useful time saving tips should still be directed to the sticky. -Narue

Well u can always use STL's "for_each" for efficiency, readability, portability & usability. Available in std::algorithm for any container types ;)


Post your tips for making life easier in C and C++. I'll start:


Standard vector object initialization

The biggest problem with the standard vector class is that one can't use an array initializer. This forces us to do something like this:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
  vector<int> v;

  v.push_back(1);
  v.push_back(2);
  v.push_back(3);
  v.push_back(4);
  v.push_back(5);

  // Use the vector
}

Anyone who's had the rule of redundancy pounded into their head knows that the previous code could be wrapped in a loop:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
  vector<int> v;

  for (int i = 1; i < 6; i++)
    v.push_back(i);

  // Use the vector
}

However, it's not terribly elegant, especially for a vector of complex types. So, Narue's first timesaving tip for C++ is to use a temporary array so that you can make use of an initializer. Because the vector class defines a constructor that takes a range of iterators, you can use the array to initialize your vector:

#include <iostream>
#include <vector>

using namespace std;

int main()
{
  int a[] = {1,2,3,4,5};
  vector<int> v(a, a + 5);

  // Use the vector
}

It is always better to avoid '_' in names until unless u want the code to be terse or STL kindastuff..it also make code less readable than the smallCaptialized form.. :-|

I know this may not seem like a super time saving technique, but the way you name your variables will help save time and reduce compile time errors.. Having a conventional variable naming format will help keep things organized and easy to read.

Styles

Typically, most variable names get the every other word capitalized. Functions get the first letter of each word capitalized and constants get all of the letters capitalized.

Example:

Variable: First letter of every other word capitalized.

  • char theName[20];

Functions: First letter of each word capitalized .

  • void GetTheName();

Constants: All capitals

  • #define THENAME 20

Of course, sometimes choosing a good variable name can take a long time!

>Well u can always use STL's "for_each" for efficiency, readability, portability & usability.
for_each isn't nearly as useful as the propaganda suggests. Also, for_each would be a poor solution to the issue that this tip covers. A better solution would be generate_n, but that's still not as concise and easy to follow Consider:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

using namespace std;

class increment {
  int _i;
public:
  increment(int start = 0): _i(start) {}
  int operator()() { return _i++; }
};

int main()
{
  vector<int> v;

  generate_n(back_inserter(v), 5, increment(1));
  copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
  cout<<endl;

  cin.get();
}

How is that better? You said for_each though, so let's look at that one too. Well, for_each requires a range for the input sequence, so you still need a temporary list, and getting the function to add to a vector isn't as trivial as you seem to think. Instead of suggesting things at random, why don't you try implementing the suggestion first to see how reasonable it is?

>it also make code less readable than the smallCaptialized form..
That's your opinion, and it's debatable.

Prototype for 'for_each':
template<class InputIterator, class Function> inline
Function for_each(InputIterator first, InputIterator last, Function F)

Following code does the insertion of integer 0 onwards in vector<int> of size 5 and prints them

void displayData(int data)
{
cout << data << "\n";
}

void setData(int& data)
{
static int i = 0;
data = i++;
}

void main()
{
std::vector<int> vecString(5);
std::for_each(vecString.begin(),vecString.end(),setData);
std::for_each(vecString.begin(),vecString.end(),displayData);
cout << "\n";
}

Output :
0
1
2
3
4

>How is that better?
Judge it by running & analyzing things

>Well, for_each requires a range for the input sequence, so you still need a >temporary list

Well why do u need a temporary list..iterators are the only thing that is required. And if u r well versed with STLs iterator are always there for any kind of container & even u can design ur iterators for ex. iterator for binary search tree etc. not present in STL.

>and getting the function to add to a vector isn't as trivial as you seem to >think.

I still say its trivial u can replace just the setData() function written above to change values to be inserted..for example reading it from file.

>Instead of suggesting things at random, why don't you try implementing the suggestion first to see how reasonable it is?

Instead of passing conclusion without going into details, why don't u listen to everybody, analyze things and make statement if its required.

I don't want to offend anybody..what we need is broader horizon to look things, may be we all learn something..excuse if my remark hurt anybody.

"Knowledge is free, share it to grow it"

>Well u can always use STL's "for_each" for efficiency, readability, portability & usability.
for_each isn't nearly as useful as the propaganda suggests. Also, for_each would be a poor solution to the issue that this tip covers. A better solution would be generate_n, but that's still not as concise and easy to follow Consider:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

using namespace std;

class increment {
  int _i;
public:
  increment(int start = 0): _i(start) {}
  int operator()() { return _i++; }
};

int main()
{
  vector<int> v;

  generate_n(back_inserter(v), 5, increment(1));
  copy(v.begin(), v.end(), ostream_iterator<int>(cout, " "));
  cout<<endl;

  cin.get();
}

How is that better? You said for_each though, so let's look at that one too. Well, for_each requires a range for the input sequence, so you still need a temporary list, and getting the function to add to a vector isn't as trivial as you seem to think. Instead of suggesting things at random, why don't you try implementing the suggestion first to see how reasonable it is?

>it also make code less readable than the smallCaptialized form..
That's your opinion, and it's debatable.

Okay, first, quotes go before responses. This makes it easier to figure out what response goes with what quote. Second, don't quote everything. That just makes the thread longer. Instead, pick out relevant statements and quote them.

>Prototype for 'for_each':
I'm quite familiar with for_each, so you don't need to tell me what it is.

>Judge it by running & analyzing things
Well, just by looking: It doesn't give the right output (0-4 instead of 1-5), you fail to include the requisite headers, you fail to qualify cout with std, you have to write two tiny functions to get for_each to work properly (thus displaying one of for_each's drawbacks), you have to make sure that vecString is properly sized from the start, vecString is a poor name, you've introduced an unnecessary static variable, and main doesn't return void (it returns int).

So I ask again, how is your use of for_each better than this, which is a better fit for your solution:

#include <algorithm>
#include <iostream>
#include <iterator>
#include <vector>

int main()
{
  int a[] = {1,2,3,4,5};
  std::vector<int> v;

  std::copy(v.begin(), v.end(), std::ostream_iterator<int>(std::cout, "\n"));
}

>Well why do u need a temporary list
To get the values. The list is either explicit through an array or other data structure, or implicit through a generator function or function object.

>..iterators are the only thing that is required
Um, do you even know what an iterator is?

>I still say its trivial
Then you're wrong. I said "add to a vector", not "assign to a vector". I'm talking about starting with an empty vector and using for_each to actually insert values into it, much like you would with copy:

int a[] = {1,2,3,4,5};
std::vector<int> v;

std::copy(a, a + 5, std::back_inserter(v));

Any idiot can write a function to assign values to an existing vector and use for_each. That's not a challenge at all, and it doesn't address the initial problem that the tip covers.

>why don't u listen to everybody, analyze things and make statement
I listened to what you said, analyzed your solution, and deemed it inappropriate. Thus my statements. Perhaps you should get your ego in check and try to understand what I'm trying to teach you. And yes, I am trying to teach you since your code suggests a lack of fundamental understanding about C++ in general and your comments display only a remedial understanding of the "STL".

This article has been dead for over six months. Start a new discussion instead.