Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Syntax clarification

Tags:

c++

syntax

ubuntu

I was browsing some of Ubuntu's Mir examples and i stumbled upon code that i couldn't understand.

struct DemoServerConfiguration : mir::DefaultServerConfiguration
{

What is going on here ": mir::DefaultServerConfiguration"?

Inside that struct there's this

std::shared_ptr<msh::PlacementStrategy> the_shell_placement_strategy()
{
   return shell_placement_strategy(
   [this]
   {
      return std::make_shared<me::FullscreenPlacementStrategy>(the_display());
   });
}

Same story here, i don't understand the syntax the unclear parts are:

<msh::PlacementStrategy> the_shell_placement_strategy()

and

return shell_placement_strategy(
       [this]
       {

Inside the same struct again

std::initializer_list<std::shared_ptr<mi::EventFilter> const> the_event_filters() override
{
    return filter_list;
}

Why the multiple <> <> <> nested? Why the the_event_filters() there?

And the last piece

mir::run_mir(config, [&config, &wm](mir::DisplayServer&)
{
    code
});

Unclear part

(config, [&config, &wm](mir::DisplayServer&)
);
like image 664
sdrubish Avatar asked Jun 20 '13 12:06

sdrubish


2 Answers

First example

That's simply a case of inheriting from an internal type:

class C
{
public:
    class Internal
    {
    };
};

class D : public C::Internal
{
    // D derives from Internal class, which is a member of C class
};

The :: is an operator of scope resolution. The expression A::B means: "B, which is a member of A". :: works for classes, structures and namespaces.

Second example

That's a little bit more complicated.

std::shared_ptr<msh::PlacementStrategy> the_shell_placement_strategy()
{
   return shell_placement_strategy(
   [this]
   {
      return std::make_shared<me::FullscreenPlacementStrategy>(the_display());
   });
}

Let's break it to parts.

std::shared_ptr<msh::PlacementStrategy> the_shell_placement_strategy()

This is a function / method the_shell_placement_strategy, which returns a result of type std::shared_ptr (generic class parametrized with msh::PlacementStrategy - see previous point).

return shell_placement_strategy(

It returns result of calling the shell_placement_strategy...

   [this]
   {
      return std::make_shared<me::FullscreenPlacementStrategy>(the_display());
   }

...which takes a lambda (nameless function) as a parameter. That nameless function wants to have access to this (thus [this]) and returns result of call to generic function std::make_shared, parametrized with me::FulscreenPlacementStrategy and called with parameter being a result of calling the_display() method / function.

You may read about lambdas elsewhere, but I'll include a short explanation for reference:

[access-specification](parameters){ body }

Where:

  • access-specification defines the relation between lambda and local variables. For example, [a] means, that lambda will have access to local variable a by value; [&a] - the same, but by reference; [&] - lambda will have access to all local variables by reference and so on.
  • parameters - regular definition of function parameters
  • body - regular body of lambda.

The lambda notation is a part of C++11 standard.

Last example

You now should be able to interpret this example:

mir::run_mir(config, [&config, &wm](mir::DisplayServer&)
{
    code
});

Thats:

  • A call to run_mir method (or function), which is a part of mir class (or namespace);
  • With two parameters: config and a function, which accepts two parameters;
  • config is passed as first parameter;
  • A lambda is passed by the second parameter.

Now the lambda:

  • It wants to access by reference two local variables: config and wm
  • It accepts one parameter of type mir::DisplayServer& (there's no name for this parameter, so it seems, that it does not actually use it
  • It does <code> :)
like image 121
Spook Avatar answered Nov 03 '22 02:11

Spook


First case, it is private inheritance. DemoServerConfiguration is derived from mir::DefaultServerConfiguration, where mir is probably a namespace (but could also be a class that declares the inner class DefaultServerConfiguration.

Second case, you are looking at lambda expression definition. You can read some introduction here.

Finally, the initializer lists are actually another feature introduced in C++11 standard (not yet supported by most of the compilers, AFAIK). Some introduction about them here.

like image 25
Cătălin Pitiș Avatar answered Nov 03 '22 01:11

Cătălin Pitiș