5

Need to have a function variable inside the class which have default functionality and it's functionality can be overwritten. Example how I liked/wanted to do(unfortunately unsuccessfully):

#include <iostream>
#include <functional>
using namespace std;

class Base
{
  public:

  std::function<bool(void)> myFunc(){
    cout << "by default message this out and return true" << endl;
    return true;}
};

bool myAnotherFunc()
{
 cout << "Another functionality and returning false" << endl;
 return false;
}

int main()
{
  Base b1;
  b1.myFunc();    // Calls myFunc() with default functionality
  Base b2;
  b2.myFunc = myAnotherFunc;
  b2.myFunc();   // Calls myFunc() with myAnotherFunc functionality
  return 0;
}

I know, this code doesn't compile. Can anyone help to fix this, or recommend something. Don't need to be std::function, if there is another way to implement this logic. Maybe should use lambda?!

Samps
  • 799
  • 6
  • 12

2 Answers2

5

Change to:

class Base {
  public:
  std::function<bool()> myFunc = [](){
    cout << "by default message this out and return true" << endl;
    return true;
  };
};

Live Demo

101010
  • 41,839
  • 11
  • 94
  • 168
  • Note that this almost unavoidably results in undefined behavior once `Base` is placed in a header file, as `[](){}` is used in each compilation unit's synthesized constructor, and has a different type id in different compilation units. This violates the ODR for the constructor. To fix this, declare `Base();` in the header, and `Base::Base() = default;` (or anything) in *exactly one* cpp file. As it happens, most compilers don't do horrible things in this case of undefined behavior *at this time*, so it will pass unnoticed. – Yakk - Adam Nevraumont Jun 16 '16 at 17:14
  • Creat! theres another problem. Look code: https://ideone.com/pO7oRZ derived class s.play() will call Base::myFunc(), which is understandable, because myFunc() is not virtual; Is there way to do this way that this play() does not call Base::myFunc(). Will call son::myFunc() – Samps Jun 16 '16 at 17:25
  • @user2440139 Take a look at [demo](http://coliru.stacked-crooked.com/a/29f789bd4273558a). – 101010 Jun 16 '16 at 18:31
  • @Yakk That's a bug that CWG needs to fix. The Itanium ABI already guarantees that the lambda has the same type in different TUs. – T.C. Jun 16 '16 at 19:12
1

Solution with minimal changes:

http://coliru.stacked-crooked.com/a/dbf33b4d7077e52b

class Base
{
  public:
  Base() : myFunc(std::bind(&Base::defAnotherFunc, this)){}

  std::function<bool(void)> myFunc;

  bool defAnotherFunc(){
    cout << "by default message this out and return true" << endl;
    return true;}
};
marcinj
  • 48,511
  • 9
  • 79
  • 100