11

It seems that the way that most people find the size of a string is they just use the my_string.size() and it works fine. Well, I recently did an assignment for class where I did...

if (size(my_string) < 5)
    store[counter].setWeight(stoi(my_string));

Instead of....

if (my_string.size() < 5)
    store[counter].setWeight(stoi(my_string));

But to my suprise my instructor, who I believe is running an older compiler, wasn't able to run that line of code. On my compiler it works both ways and I'm not quite sure why.

A complete program (it outputs 4 for both):

#include <string>
#include <iostream>
using namespace std;

int main()
{
    string myvar = "1000";
    cout << "Using size(myvar) = " << size(myvar) << endl;
    cout << "Using myvar.size() = " << myvar.size() << endl;
}

If anyone can shed some light on why my solution to the problem worked on my Machine but not my Professors? Also, I'm currently running VS2015.

Deduplicator
  • 41,806
  • 6
  • 61
  • 104
Feek
  • 287
  • 2
  • 14
  • 1
    What is the type of `temp`? What is the function `sizeof` do? – Ed Heal Oct 30 '15 at 18:27
  • 6
    interchangeable size(x) and x.size() are proposed for c++17 – Richard Hodges Oct 30 '15 at 18:29
  • Temp is of type string and temp.size() and size(temp) are both designed to get how many characters are in temp; to my surprise they both will return the same value, and size isn't defined anywhere else in my program because I thought of that as well. – Feek Oct 30 '15 at 18:29
  • 4
    Show us the **complete** program. The code you’ve shown isn’t complete and won’t compile. – Konrad Rudolph Oct 30 '15 at 18:30
  • @WillBriggs more than likely an outdated one; Richard Hodges could VS 2015 have already implemented these changes to get people used to them in c++ 17? Konrad Rudolph the sample program just containing the main method at the bottom will run on my machine, will it not run on yours? – Feek Oct 30 '15 at 18:33
  • 1
    @Feek: It's possible. [This is not valid C++14](http://coliru.stacked-crooked.com/a/6aa3ebe14ebf0500), I can tell you that much. – Lightness Races in Orbit Oct 30 '15 at 18:34
  • 1
    Out of interest, _why_ did you do it this way? Who told/taught you to? – Lightness Races in Orbit Oct 30 '15 at 18:35
  • 1
    In the Visual Studio 2015 release notes it states that "size(), empty(), and data() non-member functions are now provided. C++17". Does this imply that they have implemented what @Richard Hodges stated? – Feek Oct 30 '15 at 18:36
  • 2
    It outright proves that they have implemented what @Richard Hodges stated. – Lightness Races in Orbit Oct 30 '15 at 18:36
  • @LightnessRacesinOrbit Nobody really taught me anything about c++; All of my school taught programming languages have been Java and I just transferred to a school that is exclusively c++. So I'm having to self teach myself a lot. – Feek Oct 30 '15 at 18:37
  • Right, but you must have seen non-member `size` used somewhere .. or was it just an accident that it slipped into your code? – Lightness Races in Orbit Oct 30 '15 at 18:37
  • @RichardHodges Dunno about that, I was awfully happy with their `regex` implementation while gcc was dragging it's feet. Then again I was furious that it took them forever to implement `initializer_list`s. – Jonathan Mee Oct 30 '15 at 19:54

3 Answers3

13

size is actually C++17 functionality. The real benefit to is akin to the benefit of begin and end from C++11.

Note that the first definition of size simply returns the container's size method.

So if I have a templated function like this:

template <typename T>
auto foo(const T& bar) { return bar.size(); }

This could only be used with containers, but if I change that to:

template <typename T>
auto foo(const T& bar) { return size(bar); }

It can be used with C-style arrays too. I've added a live example here: http://melpon.org/wandbox/permlink/Rlpi5wueA14JOW2P

In summary, you should always use size and other range based functions because of the improvements to generality and container agnostic code (see here for more).

Jonathan Mee
  • 35,107
  • 16
  • 95
  • 241
  • @Deduplicator I'm aware that `void main()` is Microsoft only. Since Microsoft has the only compiler that supports this right now I figured why not. If however it irritates you so much that you must edit the answer please add a `return 0;`. I'm going to roll back for now. If you feel convicted enough to try again, and add the `return` I won't roll it back. – Jonathan Mee Oct 30 '15 at 22:48
  • @JonathanMee: In C++ and in C99+ `return 0;` at the end of `main` is implicit. Thus I didn't add it. Yes, [MS lists `void main()` as MS-specific](https://msdn.microsoft.com/en-us/library/6wd819wh.aspx), but is there any reason to restrict your code to their compiler? Other standard-libraries wil soon enough add more C++1z features. – Deduplicator Oct 30 '15 at 23:22
  • @Deduplicator Wha? `return 0` at the end of `main` is implicit? Can you give me a reference? – Jonathan Mee Oct 30 '15 at 23:39
  • 4
    In C++ see \[basic.start.main\] ("*A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling std::exit with the return value as the argument. If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;*"). – Deduplicator Oct 30 '15 at 23:42
  • In C99+ it's 5.1.2.2.3 Program termination ("*If the return type of the main function is a type compatible with int, a return from the initial call to the main function is equivalent to calling the exit function with the value returned by the main function as its argument;11) reaching the } that terminates the main function returns a value of 0. If the return type is not compatible with int, the termination status returned to the host environment is unspecified.*"). – Deduplicator Oct 30 '15 at 23:43
  • @Deduplicator I waited till I could verify that there were no warnings before rolling this back, but it appears that both gcc and Visual Studio handle the lack of a return silently. Makes you wonder what the point of `void main()` is at all... Anyway, this sure would make a great question and answer... – Jonathan Mee Nov 04 '15 at 21:08
12

MSVS 2015 has a size function defined in xutility

template<class _Container>
auto inline size(const _Container& _Cont)
    -> decltype(_Cont.size())
{   // get size() for container
return (_Cont.size());
}

This is the function that is being used when you call

cout << "Using size(myvar) = " << size(myvar) << endl;

This is not a standard C++11/14 function and will not run on gcc or clang

This was detailed in the blog post C++11/14/17 Features In VS 2015 RTM

NathanOliver
  • 150,499
  • 26
  • 240
  • 331
  • 1
    Agreed. Since it's not found in MSVS 2013, this is most likely an early implementation of a C++17 feature. (I wish they'd stop doing that -.-) [edit: confirmed by release notes - worth adding to the answer?] – Lightness Races in Orbit Oct 30 '15 at 18:36
  • @LightnessRacesinOrbit Agreed. They should make it an option – NathanOliver Oct 30 '15 at 18:40
  • 2
    As an aside, even abstaining from `using namespace std;` ([Why is “using namespace std;” considered bad practice?](http://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice)) wouldn't have changed anything due to [ADL](http://en.cppreference.com/w/cpp/language/adl), as `std::string` is also in `std`. – Deduplicator Oct 30 '15 at 20:40
3

According to http://blogs.msdn.com/b/vcblog/archive/2015/06/19/c-11-14-17-features-in-vs-2015-rtm.aspx VS2015 started to support non-member size n4280 proposal.

It's kinda weird they enable it out-of-the-box with out any define or compiler flag. But it seems like it. Currently it might be considered non-standard, although it is already voted in for c++17.

luk32
  • 15,002
  • 33
  • 58