IceTeaCup
IceTeaCup

Reputation: 33

Can someone explain me the output ? (C++11)

int main(){ 
    auto func1 = [](int y) { 
         cout << y << " "; 
    }; 
    auto func2 = [](int y) {
         cout << y * y << " "; 
    }; 
    cout << "func1 is : " << typeid(func1).name() << endl; 
    cout << "func2 is : " << typeid(func2).name() << endl;  
    cout << "main is : " << typeid(main).name() << endl; 
}

OSX output:

func1 is : Z4mainE3$_0

func2 is : Z4mainE3$_1

main is : FivE

Can someone explain the output ??

Thanks, I am just exploring some c++11 features.

Upvotes: 1

Views: 157

Answers (1)

marko
marko

Reputation: 9159

What you are seeing here is the name mangled name of each of these symbols. This is what typeid.name() for your compiler implementation returns. There is no requirement that the mangled name precisely relates directly to your code. Using the mangled symbol names already present in the object files for linking is a convenient implementation choice.

You can unmangle names using the c++filt tool: Thus:

$ c++filt _FivE

yields

int ()

In other words, a function returning an int. Remember that what you are asking for here is the type of the function and not its name.

If you were to apply this to a class

class foo
{
};

cout << "foo is : " << typeid(foo).name() << endl;

You will find output is 3foo and the unmanged name foo.

The two lambdas don't unmangle. This is because they are anonymous functions, so don't need an external name.

Furthermore, compiler generates a functor class for each lambda. The first of which would look like

struct Z4mainE3
{
    void operator()(int y)
    {
        cout << y << " ";
    }
}

This means that each one is a distinct type. The name is synthetic, and generated by the compiler such that is won't collide with anything else.

The typeid operator will operate on the functor struct and not the apparent return and argument type of the lambda itself, hence the two of them are a different type despite apparently being functions having the same signature.

The long-standing advice about typeid().name() operator is that it is not portable; you should not rely on the values returned.

Upvotes: 1

Related Questions