7

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&)
);
sdrubish
  • 199
  • 10
  • Have you read a C++ book ? Apart from the bizarre lambda syntax which might startle even a veteran since it is new in C++11, all the others are textbook examples of, respectively, inheritance and template classes. If you do not know those terms, it will take more than a SO question to bring you up to speed; I suggest you start perusing the [recommend C++ book list](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Matthieu M. Jun 20 '13 at 13:30
  • 1
    I'm certanly really poor in C++ but in my defense it was pretty much 75% lambda specific syntax, 15% parametrized typing and the rest was a short-hand syntax for internal inheritance. The :: for example which i think is "textbook" didn't need explanation – sdrubish Jun 20 '13 at 13:44
  • `struct C: foo::Base` is textbook inheritance (of a class `Base` in some scope `foo`, either another class or a namespace), the `public`, `protected` or `private` access specifiers are optional; if not precised, a `struct` inherit publicly by default while a `class` inherit privately by default. For parameterized typing, this is actually *template* in C++; the syntax can get awkward, but you should at least be familiar with `std::vector` or `std::map` for example. – Matthieu M. Jun 20 '13 at 13:47
  • You didn't need to bring more proof to validate your point i'm not trying to have an argument to convince you that i'm the better programmer of us two, i know i'm NOT :D I'll read more and become better, i just tought becoming better by receiving knowledge here counted as well btw the final 'override' keyword is new in C++11 too :P – sdrubish Jun 20 '13 at 13:57
  • Oh, I am not trying to prove anything either and I certainly apologize if it came out that way (I am afraid my mastery of English is somewhere between beginner and junior); I was just trying to convince you to open a C++ book. Q&A is great to answer quick questions, but it was my opinion that you seemed to be lacking some fundamentals and those are better taught with structured approaches as can be found in good books and tutorials. – Matthieu M. Jun 20 '13 at 14:01

3 Answers3

8

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> :)
Spook
  • 25,318
  • 18
  • 90
  • 167
  • You made me realize the question is not clear enough Thank you for the super quick answer i'm gonna edit it – sdrubish Jun 20 '13 at 12:55
  • Minor point, I don't know if you want to mention that the OP's example 1 uses private inheritance, which is different from the more common public inheritance in your example – SirGuy Jun 20 '13 at 13:04
  • 1
    @GuyGreer Someone else mentioned, that structs inherit publicly by default. This may not be a case of private inheritance. – Spook Jun 20 '13 at 13:05
  • 1
    Last example is function invocation, not definition. – Oktalist Jun 20 '13 at 13:09
  • @Oktalist Crap, my mistake. You're right of course. Modified the answer. – Spook Jun 20 '13 at 13:10
  • @Spook, ah of course. I had forgotten that little point of structs. – SirGuy Jun 20 '13 at 13:20
  • What a great answer! Thank you! I think that these 2 links could help people like me [link](http://www.informit.com/articles/article.aspx?p=376878) and [link](http://en.cppreference.com/w/cpp/language/override) – sdrubish Jun 20 '13 at 13:51
1

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.

Cătălin Pitiș
  • 14,123
  • 2
  • 39
  • 62
0
mir::DefaultServerConfiguration

Here mir could be a namespace or a class inside which DefaultServerConfiguration is defined. So for example, it could be this:

namespace mir
{
    class DefaultServerConfiguration 
    {
         /*...*/ 
    };
}

Or this,

class mir
{
 public:
    class DefaultServerConfiguration 
    {
         /*...*/ 
    };
}

In both cases, you could access the class DefaultServerConfiguration as:

mir::DefaultServerConfiguration

The same is true for other cases.

struct DemoServerConfiguration : mir::DefaultServerConfiguration
{

Here DemoServerConfiguration is a class deriving from mir::DefaultServerConfiguration. Make sense?

You also notice this in case of std::make_shared. Here std is a namespace defined by C++ Standard Library inside which the library defines make_shared function template.

Hope that helps.

Nawaz
  • 353,942
  • 115
  • 666
  • 851