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&)
);
                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.
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 parametersbody - regular body of lambda.The lambda notation is a part of C++11 standard.
You now should be able to interpret this example:
mir::run_mir(config, [&config, &wm](mir::DisplayServer&)
{
    code
});
Thats:
run_mir method (or function), which is a part of mir class (or namespace);config and a function, which accepts two parameters;config is passed as first parameter;Now the lambda:
config and wm
<code> :)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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With