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