0

I know that, given a class, say, std::array, which has a member function, say, size(), we can call on that member function via a ".", that is, in the following code,

array<int,5> myarray;
int s=myarray.size();

s would be the integer representing the size of myarray. The tricky thing happens when member functions can also be called by the namespace operator "::". For example, I know that the following line of code is valid:

auto t=chrono::high_resolution_clock::now();

Then, what's wrong with employing the syntax we originally used with array?

chrono::high_resolution_clock myclock;
auto t=myclock.now();

4 Answers4

6

now() is a static member function. This means that the function itself doesn't have a hidden this pointer. Instead, it's just like a regular function - just part of the class to avoid name collisions.

(THe high_resolution_clock is a class, chrono is a namespace, in your example. Both use :: to indicate "I want something from inside {namespace, class})

Mats Petersson
  • 126,704
  • 14
  • 140
  • 227
1

In simple terms, :: separates names from surnames, while . separates components from sub-components. (Note that in many languages like C#, Java, D, ...) there is no such distinction)

In your fist example, myarray is a variable, whose size() method refer to that particular variable.

array<int,5> myarray_a, myarray_b;
int sa=myarray_a.size();
int sb=myarray_b.size();

Will give the sizes of myarray_a and b respectively (not of array<int,5>, even if -due to this particular case- all sizes will be 5)

In the second example, now() is a static method of the class chrono::high_resolution_clock.

It doesn't matter if you have or not a variable (and how many) of type chrono::high_resolution_clock. That function does not refer to the variable but works the same for all variables of the same type (there is conceptually just one now, no matter who you ask to).

Because of this, call now() as part of a variable, of by fully qualifying its name is the same.

Note that, the size() function of std::array is strange: the size of std::array is compile time defined, hence size() could have been static as well. But std:: designers let them as member (although constexpr, so still usable in compile time expressions) to retain the same behavior as in std::array or other containers (where it has to be dynamic, and associated to a variable, since each size can vary during execution)

Emilio Garavaglia
  • 20,229
  • 2
  • 46
  • 63
0

You are mixing up 2 concepts here: "::" is used for namespaces, but also for calling static methods.

Wolfgang Ziegler
  • 1,675
  • 11
  • 23
0

There is nothing wrong with the syntax you suggested. It works.

However it creates an object, whereas the :: version does not create any object. There doesn't seem to be much point in creating that object since it is not necessary to do so in order to call the static function. So it is simpler to just call the static function without creating the object.

M.M
  • 138,810
  • 21
  • 208
  • 365
  • This is great. thanks! I actually prefer this redundancy, cause I am at a learning stage at this point. – David Roberts Jun 06 '14 at 06:33
  • "It creates an object"? Really? Do you have a source for that? How would it do so, which ctor? – MSalters Jun 06 '14 at 08:28
  • @MSalters if `X` is a class, then `X x;` (in a function or at namespace scope) creates an object `x` of type `X`. Do you really need a standard reference for that? – M.M Jun 07 '14 at 01:24
  • [See it working](http://ideone.com/Ow3Ecw). If no arguments are provided then the default constructor is used. – M.M Jun 07 '14 at 01:43
  • Sorry, misread your answer. I took it as `.` creates an object, which was a bit puzzling. – MSalters Jun 07 '14 at 07:41