Is it possible to define an anonymous member function in C++ - c++

I have a fun use case for my little pet project where I would like to have a
static map<std::string, pointer-to-member-function>
in a class. This is easy, if a bit cumbersome syntax, and it works beautifully.
What I would like to do also is to have the pointer-to-member-function be a simple lambda-expression in my static initializer. This would make it sooo easy to package things like this in a nice macro.
I want the pointer-to-member-function to have access to private class members, hence I cannot really use a normal lambda with "this" as a parameter.
However I cannot seem to find any way to define an anonymous member function -- c++ lambdas all seem to be free global functions?

If you have std::function<void(const MyClass&)> in your map then you can store a lambda that takes an instance of your class as a parameter. As long as the lambda is defined in a member function of MyClass it will be able to access private class members of MyClass:
#include <map>
#include <functional>
class MyClass {
private:
void myPrivate() const { }
public:
static std::map<std::string, std::function<void(const MyClass&)>> funcs;
static void initFuncs() {
funcs["test"] = [](const MyClass& mc) { mc.myPrivate(); };
}
};
std::map<std::string, std::function<void(const MyClass&)>> MyClass::funcs;
int main() {
MyClass::initFuncs();
MyClass mc;
MyClass::funcs["test"](mc);
}
Live demo.

Related

What are static object of class, inside the class definition, and what are different ways for calling static member function of a class?

I found a similar code like the one shown below, and two things confuse me. The first one, is it possible to have an object of the class, inside of the definition of the class, as in the example below in code 1? I though this was not possible, but maybe the static keyword is making this possible. Is this right? what is it actually happening here?
The second one, I learned that we can access static member variables and static member functions of a class just by calling the class name and the scope resolution operator (and the member we want). Apparently, the way described in code1 is an alternative manner of doing this. So, what is the main difference (or advantage) of doing it this way? In other words, what is the difference between code 1 and code 2?
//CODE 1
namespace LOGGER {
class Logger;
}
class LOGGER::Logger {
void foo(){}
public:
static Logger logger;
};
int main()
{
LOGGER::Logger::logger.foo();
}
//CODE 2
namespace LOGGER {
class Logger;
}
class LOGGER::Logger {
public:
static void foo(){}
};
int main()
{
LOGGER::Logger::foo();
}

Can I call a static method of a class by its name?

I have a bunch of classes with the same static method name, parse. I want to create a general function that calls parse for a generic class.
Can I call the method using the string name of the class, or can I pass the class as a function parameter?
The question is very broad in my opinion. I am not sure what exactly you are after but here are some options:
Have a common interface like IParser that all subclasses must implement (in this case a method Parse). You can than have one function that takes IParser&.
If you are really after the 'call by name' like some sort of RPC than I would suggest another approach where you have to register functions manually into a map of some sort that takes a pointer to the function as value, and name of the class as key. Than calling this function is as easy as map[fnName]();
C++ has no built-in reflection mechanism. If you are interested in calling method by its string representation you need to take care of name -> method pointer mapping by yourself. In this case the std::unordered_map, std::string and std::function might be helpful.
An exemplary c++11 code:
#include <iostream>
#include <unordered_map>
#include <string>
#include <functional>
struct Foo {
static std::unordered_map<std::string, std::function<void(void)>> functions;
static void bar() {
std::cout << "Foo::bar called" << std::endl;
}
static void init() {
functions["bar"] = &Foo::bar;
}
};
std::unordered_map<std::string, std::function<void(void)> Foo::functions;
int main() {
Foo::init();
Foo::functions["bar"]();
}
However if you are not interested in calling method by string only you want to call specific method of given name you could play with templates:
#include <iostream>
struct foo {
static void bar() {
std::cout << "foo::bar called" << std::endl;
}
};
template <class T>
struct tag{};
template <class T>
void call_bar(tag<T>) {
T::bar();
}
int main() {
call_bar(tag<foo>{});
}
You only need to use the scope resolution operator :: to qualify the method with the name of the class that exposes it:
Class::Method();

private member functions & structs and helpers local to the implementation file

Consider a class with a set of methods
class myClass {
private:
int someFunc(const SomeClass&);
public:
funcA();
funcB();
funcC();
}
Inside the implementation file, I have a local struct definition and some helper functions using this in an anonymous namespace
namespace {
struct Foo { ... };
int helperFunc(const Foo&){
SomeClass c;
// do stuff with Foo and SomeClass to calculate someInteger
return someInteger;
}
Foo makeFoo(){
Foo foo;
// configure foo
return foo;
}
}
myClass::funcA(){
Foo foo = makeFoo();
return helperFunc(foo);
}
myClass::funcB(){
Foo foo = makeFoo();
return helperFunc(foo);
}
myClass::funcC(){
Foo foo = makeFoo();
return helperFunc(foo)
}
Now, I discovered that I need to change the helperFunc to use someFunc(c), a private method of myClass.
Ideally, I would like to
keep the defintion of Foo local to the anonymous namespace
keep someFunc private
keep helperFunc as a function, because it's used multiple times in the class implementation
keep makeFoo separate from helperFunc, because it's used separately in some cases
As a last resort, one could convert helperFunc to a precompiler macro, but I consider this not very elegant and still hope that there is some trick that I'm unaware of to achieve my goals.
I greatly appreciate any suggestions.
You could pass an std::function object to helperFunc. This object can be constructed from your private method using std::bind:
namespace {
...
int helperFunc(const Foo&, std::function<int(const SomeClass&)> func){
SomeClass c;
...
// Invoke passed-in function
int funcResult = func(c);
...
return someInteger;
}
...
}
myClass::funcA(){
Foo foo = makeFoo();
return helperFunc(foo, std::bind(&myClass::someFunc, this, std::placeholders::_1));
}
There's more than a single way to do it. Personally, I'd go with:
namespace detail
{
int myClassSomeFuncAccessor(const SomeClass&);
}
class myClass {
private:
int someFunc(const SomeClass&);
public:
int funcA();
int funcB();
int funcC();
private:
friend int detail::myClassSomeFuncAccessor(const SomeClass&);
};
It has pros and cons.
Pros:
Decouples the class and its accessor from the implementation classes
detail namespace accessor signifies that this is not part of the "official public" interface
Cons:
The decoupling is indeed decoupled: anyone can access the internals through the detail namespace accessor
I think now is the perfect occasion of use of C++ keyword 'friend'. Simply make your inner class friend of the encapsulator. This is the cleanest and language supported solution.
In an article about the topic by Alex Allain he explains it nicely how friend in C++ are not taboo by saying
Some people believe that the idea of having friend classes violates the principle of encapsulation because it means that one class can get at the internals of another. One way to think about this, however, is that friend is simply part of a class's overall interface that it shows the world. Just like an elevator repairman has access to a different interface than an elevator rider, some classes or functions require expanded access to the internals of another class. Moreover, using friend allows a class to present a more restrictive interface to the outside world by hiding more details than may be needed by anything but the friends of the class.

pointer to member function inside namespace

I've got a namespace MyNamespace containing a class MyClass with many static public members functions.
What I need to do, is to build, inside the namespace, a map containing a pointer on every public members functions of the class
Here the code:
#include <iostream>
#include <map>
namespace MyNamespace {
class MyClass;
typedef bool (*fctPtr)(void);
typedef std::map<std::string, fctPtr> fctMap;
};
class MyNamespace::MyClass {
public:
static bool func1(void) { return true; };
static bool func2(void) { return true; };
static bool func3(void) { return true; };
static bool func4(void) { return true; };
};
MyNamespace::fctMap MyFctMap;
void execFct() {
MyNamespace::MyClass obj;
MyNamespace::fctPtr fctMemb;
fctMemb = MyFctMap["func1"];
(obj.*fctMemb)();
}
int main() {
MyFctMap["func1"] = &MyNamespace::MyClass::func1;
MyFctMap["func2"] = &MyNamespace::MyClass::func2;
MyFctMap["func3"] = &MyNamespace::MyClass::func3;
MyFctMap["func4"] = &MyNamespace::MyClass::func4;
execFct();
}
And what the compiler says:
% clang++ draft.cc
draft.cc:29:7: error: right hand operand to .* has non pointer-to-member type
'MyNamespace::fctPtr' (aka 'bool (*)()')
(obj.*fctMemb)();
^ ~~~~~~~
1 error generated.
I don't understand why I got this error neither what to do to resolve the problem. Idea?
Edit: I'm using c++98 and no boost.
Working with a typedef bool (MyClass::*fctPtr)(void) drives me to this kind od error, at map assignment time.
error: assigning to 'mapped_type' (aka 'bool (MyNamespace::MyClass::*)()') from
incompatible type 'bool (*)()'
MyFctMap["func1"] = &MyNamespace::MyClass::func1;
^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Since the functions you are referencing are static, you don't need the obj class reference. Simply call fctMemb();. You might also consider if you need these functions mapped in such a way, oftentimes you don't need that dynamic aspect to function references in C++ and instead should be using templates.
A pointer to a function is not the same as a pointer to a member function. The important thing to remember is that all (non-static) member function actually have a hidden first argument which is what becomes the this pointer. Therefore a function pointer and a member function pointer can't ever be compatible.
However, you should look into std::function and std::bind:
namespace NyNamespace
{
typedef std::function<bool()> fctPtr;
...
}
MyNamespace::MyClass myObject;
MyFctMap["func1"] = std::bind(&MyNamespace::MyClass::func1, myObject);
The idea is fctMemb(); :-)
fctPtr, as the compiler says, is not a pointer to member type...
Static member functions are not like normal member functions. They have access to class private and protected members, but they are not tied to object instances and thus can't access this pointer nor any non-static members.
Their type is that of normal function pointers and they can't be bound to member function pointers (and normal function pointers is what you have in your code).
You call them like normal functions:
fctMemb();
Btw, the sytax to form member function pointers is different:
struct Foo {
void f() {}
};
void (Foo::* mem_fun_ptr)() = &Foo::f;

typedef function pointer that takes argument ClassName* before defining ClassName?

I have the following situation:
typedef void (*F_POINTER)(ClassName*);
class ClassName {
public:
F_POINTER f;
}
This happens because an instance of ClassName needs to pass a pointer itself to the client. However, If I write things in this order, I get complains about ClassName not declared, whatnot. However, if I switch them around, I get complains about F_POINTER not being declared when I declare the instance in the class.
So maybe I'm missing something simple here, but how would I accomplish this?
Forward declaration:
class ClassName;
typedef (*F_POINTER)(ClassName*);
class ClassName {
public:
F_POINTER f;
}
Or shorter:
typedef (*F_POINTER)(class ClassName*); // implicit declaration;
This seems to be working under GCC 4.5.2 (mingw32):
typedef void (*F_POINTER)(class ClassName);
class ClassName {};
void f (ClassName) {}
int main ()
{
F_POINTER x = f;
}
I wouldn't trust my life on whether it is legal C++ or not, not even the pointer version described by other people. Forward declarations and pointers do not solve everything, for example it is not possible to declare methods that throw pointers of incomplete types, you need full definition for that. This might be similarly illegal, just accepted by compilers.
Forward declare ClassName. The type can be incomplete to use a pointer to it.
class ClassName;
typedef (*F_POINTER)(ClassName*);
class ClassName { ... };
Alternatively, move the typedef inside the class. Also consider using boost::function/std::function instead of function pointers.
Either you can forward declare it as,
class ClassName;
typedef void (*F_POINTER)(ClassName*); // assume that return is `void`
before the F_POINTER or you can use the template trick to avoid such hassels for every class:
template<typename RETURN, typename ARGUMENT>
struct FuncPtr { typedef RETURN (*F_POINTER)(ARGUMENT); };
Usage:
class ClassName {
public:
FuncPtr<void,ClassName*>::F_POINTER f;
};