3

When using Visual Studio, I can write a container traversal in at least the following three ways. Which way is preferable? Assuming:

vector<CString> strings1;

Method 1 (using the for_each algorithm with a lambda:

for_each(strings1.begin(), strings1.end(), [](CString s){
   _tprintf(_T("%s"), s);
}

Method 2 (using for each, in, microsoft specific):

for each(auto s in strings1)
{
   _tprintf(_T("%s"), s);
}

Method 3 (treat the vector with array syntax):

for (int i=0; i<v.size(); ++i)
{
   _tprintf(_T("%s"), v[i]);
}

I am aware that method 2 is not portable, but I don't care about being portable. This only needs to work in Windows.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
Mike Caron
  • 5,674
  • 4
  • 48
  • 71
  • 3
    the latter is clearer, seems like a style thing tbh.. – Nim Feb 07 '12 at 19:55
  • 2
    With C++11 just use `for (auto x : v) ...` instead of #2 (not in MSVC10 though). – Georg Fritzsche Feb 07 '12 at 19:56
  • 1
    Unless you tag the question as `c++-cli` the second is not an option (it is not proper C++, not just not portable but invalid) – David Rodríguez - dribeas Feb 07 '12 at 20:03
  • @DavidRodríguez-dribeas my C++ project doesn't define /CLI, and method 2 still compiles with VC 2010. – Mike Caron Feb 07 '12 at 20:05
  • @MikeCaron: Does not change the fact its not valid C++. – Martin York Feb 07 '12 at 20:08
  • I thought he was operating in C#. Answer deleted. – Almo Feb 07 '12 at 20:09
  • In MS Visual C++ 2010, Method 2 certainly is valid C++. It may not be standards-compliant, but it compiles and runs without /clr (or MFC or ATL for that matter). – Mike Caron Feb 07 '12 at 20:23
  • If the `for each` syntax is based off an earlier draft then presumably it will not be supported in the future once the standard syntax is supported. – bames53 Feb 07 '12 at 20:39
  • @bames53 Yes, I agree. It's probably dangerous to use this as it might become deprecated in a future version of vs. – Mike Caron Feb 07 '12 at 20:44
  • @MikeCaron: "In MS Visual C++ 2010, Method 2 certainly is valid C++." Just because a C++ compiler compiles it *does not make it C++*. Many compilers add language extensions. Those language extensions do not magically become valid C++ just because a compiler supports them. They only become C++ when the **standard** says they do. That is what defines the language, not your compiler. – Nicol Bolas Feb 07 '12 at 21:05
  • 1
    @MikeCaron: I don't understand the purpose of your question. You say that "I don't care about being portable." Then... why ask us? If all you're and anyone who compiles your code will ever use is Visual Studio 2010, then just use the language extension. That's who language extensions are written for: people who have picked their compiler and will be sticking with it. – Nicol Bolas Feb 07 '12 at 21:06
  • @MikeCaron It only compiles with language extensions enabled (which on the other hand is by default). If you disable language extensions then it does not compile any more. – David Rodríguez - dribeas Feb 07 '12 at 21:59
  • @NicolBolas That's a valid comment. Sure, if I only care about VStudio, I can use the extension. I made a distinction between valid and standards-compliant; valid meaning that it would compile and run. – Mike Caron Feb 07 '12 at 22:06
  • @DavidRodríguez-dribeas Thanks! I didn't know about the language extensions being default. – Mike Caron Feb 07 '12 at 22:07

3 Answers3

5

In C++11 you can use range based for which is similar to method 2, but standard.

http://www2.research.att.com/~bs/C++0xFAQ.html#for

zch
  • 14,931
  • 2
  • 41
  • 49
  • Unfortunately VS2010 doesn't support the final syntax but an earlier version of it; see here: http://stackoverflow.com/questions/6898859/does-msvc10-visual-studio-2010-support-c-range-based-loops – Peter Feb 07 '12 at 20:02
  • In lieu of VS 2011 beta, what would your answer be? – Mike Caron Feb 07 '12 at 20:28
3

As Stephan T. Lavavej pointed out just a couple of days ago at the "GoingNative 2012" conference, the "official" range-based for loop will be part of the soon-to-be-released beta version of the new Visual Studio. So this will be the way to go:

for(auto s : strings1)
{
   _tprintf(_T("%s"), s);
}

or use a reference to reduce copying effort for the by-value use:

for (auto &s : strings1)  ....

Edit: the GoingNative talk mentioned above can be found here

Piotr99
  • 531
  • 3
  • 12
  • chose yours as the answer because of included code. S.T.L. is awesome. – Mike Caron Feb 08 '12 at 17:54
  • Thanks! I almost agree -- but STL and C++11 is even more awesome ;) – Piotr99 Feb 08 '12 at 18:07
  • Is the Beta version different from the current developer preview? I just installed the DP and it doesn't have the range-based iterator. – Mike Caron Feb 08 '12 at 18:12
  • Phew... no idea... I don't use Visual Studio myself, so I didn't check his statement. I just picked it up incidentally from the video. I guess you have to watch the video yourself or at least take a look at the slides. Anyway, the videos are very instructive, even for me programming mostly for Linux and Mac. Not a surprise though, as they've invited the godfathers of C++ – Piotr99 Feb 08 '12 at 18:35
  • Now I'm starting to feel in doubt whether it was Stephan Lavavej's talk or maybe Herb Sutter's talk. The latter might be worth to take a look for this, too. – Piotr99 Feb 08 '12 at 18:43
  • STL does say the range based for loop will be in the beta. The beta and the DP are not the same. STL also refers to the `for each` version as "that horrible, horrible thing" [at 53:10 in his talk] and says that the range based loop is strictly better than `for each`. – bames53 Feb 10 '12 at 01:06
1

While I think the syntax of the second option is clearer, I'd personally prefer to avoid it since it's based on an earlier version of the draft standard and hence seems liable to change in the future. YMMV though since it's mostly a question of taste.

Peter
  • 7,216
  • 2
  • 34
  • 46