#include <array>
#include <cassert>
#include <cstddef>
#include <functional>
template <std::size_t N>
class BaseClass {
public:
virtual std::array<int, N> CustomBehavior(const std::array<int, N>& user_array, int user_number) = 0;
protected:
std::array<int, N> my_array = {0, 0};
};
template <std::size_t N>
class DerivedClass : public BaseClass<N> {
public:
DerivedClass() = default;
DerivedClass(std::function<std::array<int, N>(const std::array<int, N>&, int)> custom_f)
: customCallback(std::bind(custom_f, std::placeholders::_1, std::placeholders::_2)) {}
void SetCustomBehavior(std::function<std::array<int, N>(const std::array<int, N>&, int)> custom_f) {
customCallback = std::bind(custom_f, std::placeholders::_1, std::placeholders::_2);
}
std::array<int, N> CustomBehavior(const std::array<int, N>& user_array, int user_number) override {
if (customCallback)
this->my_array = customCallback(user_array, user_number);
return this->my_array;
}
private:
std::function<std::array<int, N>(const std::array<int, N>&, int)> customCallback;
};
static constexpr std::size_t MySize = 2;
std::array<int, MySize> my_behavior(const std::array<int, MySize>& input_array, int a) {
return {a * input_array[0], a * input_array[1]};
}
int main() {
std::array<int, MySize> my_array = {1, 1};
// Default constructor
DerivedClass<MySize> foo_1; // OK
std::array<int, MySize> bar_1 = foo_1.CustomBehavior(my_array, 2);
assert(bar_1[0] == 0 && bar_1[1] == 0);
// Custom constructor
DerivedClass<MySize> foo_2(my_behavior); // OK
std::array<int, MySize> bar_2 = foo_2.CustomBehavior(my_array, 2);
assert(bar_2[0] == 2 && bar_2[1] == 2);
// Default constructor with custom behavior set later on
DerivedClass<MySize> foo_3; // OK
foo_3.SetCustomBehavior(my_behavior); // OK
std::array<int, MySize> bar_3 = foo_3.CustomBehavior(my_array, 2);
assert(bar_3[0] == 2 && bar_3[1] == 2);
return 0;
}
I2luY2x1ZGUgPGFycmF5PgojaW5jbHVkZSA8Y2Fzc2VydD4KI2luY2x1ZGUgPGNzdGRkZWY+CiNpbmNsdWRlIDxmdW5jdGlvbmFsPgoKdGVtcGxhdGUgPHN0ZDo6c2l6ZV90IE4+CmNsYXNzIEJhc2VDbGFzcyB7CnB1YmxpYzoKICAgIHZpcnR1YWwgc3RkOjphcnJheTxpbnQsIE4+IEN1c3RvbUJlaGF2aW9yKGNvbnN0IHN0ZDo6YXJyYXk8aW50LCBOPiYgdXNlcl9hcnJheSwgaW50IHVzZXJfbnVtYmVyKSA9IDA7ICAgIApwcm90ZWN0ZWQ6CiAgICBzdGQ6OmFycmF5PGludCwgTj4gbXlfYXJyYXkgPSB7MCwgMH07Cn07Cgp0ZW1wbGF0ZSA8c3RkOjpzaXplX3QgTj4KY2xhc3MgRGVyaXZlZENsYXNzIDogcHVibGljIEJhc2VDbGFzczxOPiB7CnB1YmxpYzoKICAgIERlcml2ZWRDbGFzcygpID0gZGVmYXVsdDsKCiAgICBEZXJpdmVkQ2xhc3Moc3RkOjpmdW5jdGlvbjxzdGQ6OmFycmF5PGludCwgTj4oY29uc3Qgc3RkOjphcnJheTxpbnQsIE4+JiwgaW50KT4gY3VzdG9tX2YpCiAgICAgICAgOiBjdXN0b21DYWxsYmFjayhzdGQ6OmJpbmQoY3VzdG9tX2YsIHN0ZDo6cGxhY2Vob2xkZXJzOjpfMSwgc3RkOjpwbGFjZWhvbGRlcnM6Ol8yKSkge30KCiAgICB2b2lkIFNldEN1c3RvbUJlaGF2aW9yKHN0ZDo6ZnVuY3Rpb248c3RkOjphcnJheTxpbnQsIE4+KGNvbnN0IHN0ZDo6YXJyYXk8aW50LCBOPiYsIGludCk+IGN1c3RvbV9mKSB7CiAgICAgICAgY3VzdG9tQ2FsbGJhY2sgPSBzdGQ6OmJpbmQoY3VzdG9tX2YsIHN0ZDo6cGxhY2Vob2xkZXJzOjpfMSwgc3RkOjpwbGFjZWhvbGRlcnM6Ol8yKTsKICAgIH0KCiAgICBzdGQ6OmFycmF5PGludCwgTj4gQ3VzdG9tQmVoYXZpb3IoY29uc3Qgc3RkOjphcnJheTxpbnQsIE4+JiB1c2VyX2FycmF5LCBpbnQgdXNlcl9udW1iZXIpIG92ZXJyaWRlIHsKICAgICAgICBpZiAoY3VzdG9tQ2FsbGJhY2spCiAgICAgICAgICAgIHRoaXMtPm15X2FycmF5ID0gY3VzdG9tQ2FsbGJhY2sodXNlcl9hcnJheSwgdXNlcl9udW1iZXIpOwogICAgICAgIHJldHVybiB0aGlzLT5teV9hcnJheTsKICAgIH0KCnByaXZhdGU6CiAgICBzdGQ6OmZ1bmN0aW9uPHN0ZDo6YXJyYXk8aW50LCBOPihjb25zdCBzdGQ6OmFycmF5PGludCwgTj4mLCBpbnQpPiBjdXN0b21DYWxsYmFjazsKfTsKCnN0YXRpYyBjb25zdGV4cHIgc3RkOjpzaXplX3QgTXlTaXplID0gMjsKCnN0ZDo6YXJyYXk8aW50LCBNeVNpemU+IG15X2JlaGF2aW9yKGNvbnN0IHN0ZDo6YXJyYXk8aW50LCBNeVNpemU+JiBpbnB1dF9hcnJheSwgaW50IGEpIHsKICAgIHJldHVybiB7YSAqIGlucHV0X2FycmF5WzBdLCBhICogaW5wdXRfYXJyYXlbMV19Owp9CgppbnQgbWFpbigpIHsKCiAgICBzdGQ6OmFycmF5PGludCwgTXlTaXplPiBteV9hcnJheSA9IHsxLCAxfTsKCiAgICAvLyBEZWZhdWx0IGNvbnN0cnVjdG9yCiAgICBEZXJpdmVkQ2xhc3M8TXlTaXplPiBmb29fMTsgLy8gT0sKICAgIHN0ZDo6YXJyYXk8aW50LCBNeVNpemU+IGJhcl8xID0gZm9vXzEuQ3VzdG9tQmVoYXZpb3IobXlfYXJyYXksIDIpOwogICAgYXNzZXJ0KGJhcl8xWzBdID09IDAgJiYgYmFyXzFbMV0gPT0gMCk7CgogICAgLy8gQ3VzdG9tIGNvbnN0cnVjdG9yCiAgICBEZXJpdmVkQ2xhc3M8TXlTaXplPiBmb29fMihteV9iZWhhdmlvcik7IC8vIE9LCiAgICBzdGQ6OmFycmF5PGludCwgTXlTaXplPiBiYXJfMiA9IGZvb18yLkN1c3RvbUJlaGF2aW9yKG15X2FycmF5LCAyKTsKICAgIGFzc2VydChiYXJfMlswXSA9PSAyICYmIGJhcl8yWzFdID09IDIpOwoKICAgIC8vIERlZmF1bHQgY29uc3RydWN0b3Igd2l0aCBjdXN0b20gYmVoYXZpb3Igc2V0IGxhdGVyIG9uCiAgICBEZXJpdmVkQ2xhc3M8TXlTaXplPiBmb29fMzsgIC8vIE9LCiAgICBmb29fMy5TZXRDdXN0b21CZWhhdmlvcihteV9iZWhhdmlvcik7IC8vIE9LCiAgICBzdGQ6OmFycmF5PGludCwgTXlTaXplPiBiYXJfMyA9IGZvb18zLkN1c3RvbUJlaGF2aW9yKG15X2FycmF5LCAyKTsKICAgIGFzc2VydChiYXJfM1swXSA9PSAyICYmIGJhcl8zWzFdID09IDIpOwoKICAgIHJldHVybiAwOwp9