Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why Can't I constexpr a bind?

So say that I want to make some constexpr functors, I though I could do this using bind. Is there something I'm missing? Why can't bind return a constexpr?

Given:

struct foo {
    int b() const { return _b; }
    int a() const { return _a; }
    int r() const { return _r; }
    const int _b;
    const int _a;
    const int _r;
};

I want to:

constexpr auto sumB = bind(plus<int>(), placeholders::_1, bind(&foo::b, placeholders::_2));
constexpr auto sumA = bind(plus<int>(), placeholders::_1, bind(&foo::a, placeholders::_2));
constexpr auto sumR = bind(plus<int>(), placeholders::_1, bind(&foo::r, placeholders::_2));

Is there something I could do to make this work?

like image 591
Jonathan Mee Avatar asked Jan 30 '23 21:01

Jonathan Mee


2 Answers

There is no technical obstacle to making bind constexpr; for example, the Sprout C++ Libraries have a constexpr-enabled bind.

However, implementations are not permitted to add constexpr to function signatures where it is not specified in the Standard, and there has not yet been any proposal to add constexpr to bind that I am aware of (Which parts of the C++14 Standard Library could be and which parts will be made constexpr?). It is fairly unlikely that one would be forthcoming, since bind is mostly superseded by lambda expressions, which as of C++17 are automatically constexpr:

constexpr auto sumB = [](int x, foo const& y) { return x + y.b(); };
like image 196
ecatmur Avatar answered Feb 08 '23 15:02

ecatmur


Well, we don't know what std::bind returns. It could probably be made to work but there is nothing mandated to make it work (nothing is defined as constexpr in std::bind's specification).

On thing you can do though, if you have access to C++17, is to use a lambda. In C++17 the operator() of the lambda will be marked constexpr by default allowing you to do something like

constexpr auto sumB = [](auto val, auto obj) { return val + obj.b(); };
constexpr auto sumA = [](auto val, auto obj) { return val + obj.a(); };
constexpr auto sumR = [](auto val, auto obj) { return val + obj.r(); };

Live Example

like image 24
NathanOliver Avatar answered Feb 08 '23 15:02

NathanOliver