Skip to content

Instantly share code, notes, and snippets.

@brunoalr
Created May 25, 2022 07:40
Show Gist options
  • Save brunoalr/7fcf786a7342b21ff22b2fa93d1d90db to your computer and use it in GitHub Desktop.
Save brunoalr/7fcf786a7342b21ff22b2fa93d1d90db to your computer and use it in GitHub Desktop.
fun with pointers to member functions
// https://godbolt.org/z/3s1r3K4rs
#include <string>
// For c++ versions earlier than 17
#if __cplusplus < 201703L
// See https://isocpp.org/wiki/faq/pointers-to-members#macro-for-ptr-to-memfn
// and https://isocpp.org/wiki/faq/big-picture#use-evil-things-sometimes
#define CALL_MEMBER_FN(object,ptrToMember) (((object).*(ptrToMember))())
#else
#include <functional>
#define CALL_MEMBER_FN(object, ptrToMember) (std::invoke(ptrToMember, object))
#endif
struct ThingHolder {
std::string thing1;
std::string thing2;
std::string thingN;
};
class Builder {
public:
Builder& setThing1(std::string aThing1)
{
mThing.thing1 = std::move(aThing1);
return *this;
}
Builder& setThing2(std::string aThing2)
{
mThing.thing2 = std::move(aThing2);
return *this;
}
Builder& setThingN(std::string aThingN)
{
mThing.thingN = std::move(aThingN);
return *this;
}
const ThingHolder build() const
{
return mThing;
}
private:
ThingHolder mThing;
};
struct Getter {
std::string thing1;
std::string thing2;
std::string thingN;
const std::string& GetThing1() const
{
return thing1;
}
const std::string& GetThing2() const
{
return thing2;
}
const std::string& GetThingN() const
{
return thingN;
}
};
int main() {
using GetterMemFn = const std::string& (Getter::*)(void) const;
Getter objA;
objA.thing1 = "1";
Getter objB;
objB.thing2 = "123";
const auto magicFunction = [&objA, &objB](const GetterMemFn& memFn) {
return !CALL_MEMBER_FN(objA, memFn).empty() ?
CALL_MEMBER_FN(objA, memFn) :
CALL_MEMBER_FN(objB, memFn);
};
const auto thingHolder {
[&]{
return Builder{}
.setThing1(magicFunction(&Getter::GetThing1))
.setThing2(magicFunction(&Getter::GetThing2))
.setThingN(magicFunction(&Getter::GetThingN))
.build();
}()
};
return thingHolder.thing1.size();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment