7

My question refers to:

Using a lambda expression versus a private method

Now that lambda functors are part of C++, they could be used to unclutter a class' interface. How does lambda use vs private method use compare in C++? Do there exist better alternatives to unclutter class interfaces?

Community
  • 1
  • 1
user1095108
  • 14,119
  • 9
  • 58
  • 116
  • 9
    What have private methods to do with a class interface? – Kerrek SB Sep 14 '13 at 19:22
  • 1
    @KerrekSB They are a part of it. You have heard of the `friend` keyword. – user1095108 Sep 14 '13 at 19:41
  • 3
    friend keyword is a realy bad practice, if you use the friend keyword, you have a design problem. And besides, that still does not make them part of the classe's interface, as non-friend classes or methods won't be able to use them. – user1708860 Sep 14 '13 at 19:42
  • 1
    @user1708860 I disagree, `find -name "*.h" | xargs grep friend | wc -l` in `qtbase` of `Qt5`, currently shows `1272`. There could be other examples made as well. Also, if you make any use of a private member, I consider it a part of the class interface, albeit a private one. – user1095108 Sep 14 '13 at 19:47
  • 2
    Just one example from a quick google search. http://stackoverflow.com/questions/203616/why-does-c-sharp-not-provide-the-c-style-friend-keyword?rq=1 just because a library that is common use it, does not make it good, you can never tell why they used it. – user1708860 Sep 14 '13 at 19:50
  • 7
    @user1708860 That’s clean nonsense. The answer you link to is heavily downvoted by actual C++ experts (as opposed to C# folks, who apparently upvoted it), and comments explain why it’s wrong. – But it doesn’t change the fact that `private` functions are *not* part of the class’ interface. – Konrad Rudolph Sep 14 '13 at 19:53
  • 1
    As for the interface part, you should first define the term "class interface" in c++. If you look at other languages, or http://en.wikipedia.org/wiki/Application_programming_interface then you realise that private methods and members do not enter the category of class interface. – user1708860 Sep 14 '13 at 19:56
  • 1
    @user1708860 I suppose you are a Pimpl and Bridge proponent. – user1095108 Sep 14 '13 at 19:58
  • @KonradRudolph, thanks you changed my mind about the encapsulation part about friend, altough, i still think your design should be reconsidered if you use friend. And as i said, the link was just the first thing i googled.user1095108, i kinda am :) – user1708860 Sep 14 '13 at 20:10
  • 1
    private function is a part of the interface, the old way of `= delete` for non copyable per example. in addition Private functions take part during the overload resolution (`class A{void f(char); public: f(float)}; a.f(42); // failed`), so it interferes with the public interface. – Jarod42 Sep 15 '13 at 11:03

5 Answers5

5

Do there exist better alternatives to unclutter class interfaces?

A method I use quite often is to provide a series of functions with file-scope in an unnamed namespace that act as "helpers" to my member functions.

For example:

// Foobar.cpp
#include "Foobar.h"

namespace {

    void someHelper()
    {
        std::cout << "I'm a helper!" << std::endl;
    }

}


void Foobar::someMemberFunc()
{
    someHelper();
    [...]
}

You can, of course, also declare lambdas and/or classes in this unnamed namespace as well. Anything declared in this unnamed namespace will only be accessible from within the same translation unit (eg, cpp file).

Bret Kuhns
  • 4,034
  • 5
  • 31
  • 43
  • 2
    This does not solve many of the problems when you need access to the object's private members, unless you declared them public and passed them as a parameter, but then i can only wish you good luck and have fun :) – user1708860 Sep 14 '13 at 19:28
  • 2
    @user1708860 I consider that these methods can't access private members as a good thing. Functions that maintain an object's invariance should definitely be members. Anything that does NOT maintain invariance is best left outside the class. If needed by clients, then a non-member function with external linkage is best. If, however, the members need "helpers" that aren't generally reusable, the idiom I present maintains strong encapsulation without polluting namespaces/interfaces and really helps keep build times down. – Bret Kuhns Sep 14 '13 at 21:37
  • 1
    you could always use a details namespace allowing to you make it unit testable as well. – gda2004 Dec 15 '15 at 08:31
5

Although lambdas can definitely replace some private member functions, thinking of them as means to uncluttering the interface of a class is taking too narrow a view of both lambdas and private member functions.

Private member functions (and functions in general) are the basic units of code reuse. They let you write a piece of logic once, and then hide it behind the name of the function.

Although lambdas can replace a private member function in certain context, they could replace an object of which that function is a member along with it, which is a whole lot more. Due to lambda's ability to capture the context around them, you get a way of creating code blocks that take not only your object with it, but also the state of your local variables. Before lambdas you needed to create a special class for that; lambdas let you create such classes on the fly, for much better readability.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • Yeah, you don't need extra private members or a separate class for storing local state, but how about their use for information hiding? Do you mean to say, if there is local state to be saved use a lambda, otherwise use a private function? – user1095108 Sep 14 '13 at 20:08
  • 1
    @user1095108 Ironically, it's public methods that help you with information hiding, because they hide the details of the implementation from your callers. Not being part of your class interface, private methods are themselves hidden from the users of your class; unlike public methods that hide information from the users, from the point of view of the callers, your private methods do not exist. Same goes for lambdas (unless you define a public var of lambda type): they are entirely hidden from the callers. – Sergey Kalinichenko Sep 14 '13 at 20:21
  • Aren't lambda objects equivalents of functions and more (as you note). Shouldn't they be considered a possible replacement of the usual function in all situations? They can be reused, they can be copy pasted. I don't know how to understand your post. Lambdas can do "a whole lot more" than private member functions, so why aren't they superior? – user1095108 Sep 14 '13 at 21:44
  • 1
    @user1095108 Lambdas replace private functions in one case - when you need to pass a piece of code to another function that needs to call you back. Lambdas give you more flexibility at that than private functions do. However, there are other places where you need functions where lambdas will not do - e.g. private virtual functions that subclasses can override, or shared pieces of logic that you need to eliminate copy-paste. The point is, even in systems where you do not have a single callback you would still use private functions for code organization; lambdas would be useless in this context. – Sergey Kalinichenko Sep 14 '13 at 22:18
  • You can put a lambda into a `std::function` and adapt it this way to be useful in more situations. It can be shared this way, perhaps even overridden (by assignment). – user1095108 Sep 14 '13 at 23:01
  • @user1095108 When you put a lambda into `std::function` you adapt it for use in callback-like situations (i.e. when you need to pass an encapsulated piece of logic to a function). Lambdas are so versatile that you can model overrides with them, but you would break idiomatic ways of C++ by using lambdas instead of plain functions that you intend to override. – Sergey Kalinichenko Sep 15 '13 at 01:14
3

How does lambda use vs private method use compare in C++

One may capture the this pointer, therefore having access to a class's internals without cluttering its interface. Previously, under certain circumstances one would require either a member or a friend function (use in conjunction with bind and mem_fn) in stl algorithms.

Added, one should strive to keep interfaces minimal, as changing them is more costly. For this reason idioms like pimpl are popular, and for the same reason a lambda may be preferred over a member function. As mentioned by another person, one should consider that functions are also tools of reuse, but in that case I would prefer a pimpl with private functions, which negates reuse of lambdas for this purpose.

Werner Erasmus
  • 3,988
  • 17
  • 31
3

Lambda is a way to move logic into the flow of your code. The only purpose is improving readability, and they can help or they can hurt

  • If a private/lambda is short, it is often easier for a reader to comprehend it on the spot, rather than having to remember to look at a different function later.
  • If a private/lambda is long, and appears incongruous with the code calling it, this can distract the reader from a greater pattern in the code. Imagine if you were reading one of these StackOverflow answers and suddenly had to stop to read StackEnglish's description of null and void to make sense of the answer. You'd really rather just see a hyperlink of "optional information" than a copy/paste of the contents.
  • It is far easier to construct a lambda which holds onto upvalue arguments than it is to construct a private functor to do the same. This can increase readability due to lambdas having less boilerplate in accomplishing that goal.
  • lambdas are harder to share between sections of code. If you find yourself calling the same function from many places, private functions may be a better match.
Community
  • 1
  • 1
Cort Ammon
  • 10,221
  • 31
  • 45
2

It has a matter of personal taste in it if you ask me, the difference between the two is not huge.

Lambdas are really good for stl algorithms, while private methods, are not as comftorable for that, on the other hand, i find private methods much better if you want to reuse your code.

This question shows the best usages of lambdas imo : lambdas

Personally, i prefer private methods, espessialy in the case you presented. Lambdas should not be used instead of private methods. It clutters the function's body and diverts the eye from the main logic.

Although it unclutter the class, it clutters the function, which i find worse.

Community
  • 1
  • 1
user1708860
  • 1,683
  • 13
  • 32