Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between type and name in C++?

Tags:

I am reading this Stack Overflow question, and I added a constructor to the code from that question as the follwing,

class Foo {     struct Bar {          int i;          Bar(int a = 5) :i(a) {};      };    public:     Bar Baz() { return Bar(); } };  int main() {     Foo f;     // Foo::Bar b = f.Baz();  // error     auto b = f.Baz();         // ok     std::cout <<"b.i="<< b.i<<endl;     return 0; } 

The code outputs b.i=5. In that question it concludes that the name of the private is not accessible but the type is. So what's the difference between type and name, generally?

And say I have two specific scenarios.

  1. What's the difference between the following two declarations? Why can I get the output b.i=5 from auto b = f.Baz();?

    Foo::Bar b = f.Baz(); auto b = f.Baz(); 
  2. If I add typedef Bar B; in the public part of Foo, what is the difference between the following?

     Foo::Bar b = f.Baz();  Foo::B   b = f.Baz();  

If there a difference between scenario 1 and 2?

like image 855
Allanqunzi Avatar asked May 14 '15 18:05

Allanqunzi


1 Answers

What is the difference between type and name

A type has none, one or several names. Typedef and alias are simply means of creating a new name for a type.

public and private keywords relate to names not to the underlying types or members.

In order to explicitly declare an object of a particular type you need a name for that type. auto doesn't need this. If you for example use an unnamed class as a return type, this class has no name but auto can still be used on it.

An type will always have at most one 'true name'. Even when using it through a typedef or alias, the compiler uses it under this name (or actually the raw version of this name). So:

class A {}; typedef A B; std::cout << typeid(B).name(); 

Prints "class A". An unnamed object cannot be given a 'true name'. However, when using typedef and decltype. A new name can be created. If this name is then used to create objects. typeid().name will print the newly assigned name. If the object wasn't unnamed to start with the 'true name' name will be printed.


The scenarios:

  1. The difference is that in the first you are using a privately declared name. Which is illegal. This has to do with how the different ways of type deduction work. As Scott Meyers explains here. Since a public function call provides this type, the return type is public. However, Bar on itself is not public. It's a small difference, but that is the reason.

    This simply is a decision that has been made in the design. It makes sense, sometimes you only want a struct to be used when you return it.

  2. The same goes here. There is no difference, however Foo::Bar simply is inaccessible.


Edit

Can you give an example that type has none names? is the unnamed union in the above comment a example of this?

As described here I use a lambda function as follows:

auto f = [] () -> struct {int x, y ; } { return { 99, 101 } ; } ; 

Without using auto or decltype there would be no way of creating variable f. Since it's type has no name. Another example of a type without a name.

struct foo {     struct{         int x;         int y;     } memberVar; }; 

Would allow you to do the following:

foo bar;  auto baz = bar.memberVar;  std::cout << baz.x; 

Which results in a bunch of initialized stuff of course, but you get the idea:). The type of memberVar here is unnamed. Making it impossible to define baz explicitly.

And is int considered to be a name for type of int?

int is a bit special, being a fundamental type. 'int' indeed is the name of the type int. But it's by no means the only name, int32_t, for example is another name for the exact same type on most compilers(on other systems int16_t is equivalent to int).

std::cout << typeid(int32_t).name();  

Prints "int".

Notes:

  • I've refrained from using alias as an indicator for other names of an object, since this might cause confusion with the alias keyword.

  • Most of this I have gathered from experience. So I might have missed some bits.

  • By lack for a better word i have used the expression 'true name'. If anybody knows the official or a better word for this i'd be happy to hear it:).

like image 152
laurisvr Avatar answered Sep 20 '22 05:09

laurisvr