2017-07-28 1 views
3

Also sagen, dass ich einige constexpr Funktoren machen möchte, obwohl ich dies mit bind tun könnte. Gibt es etwas, das mir fehlt? Warum kann bind keine constexpr zurückgeben?Warum kann ich keine Bindung constexpr?

Gegeben:

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; 
}; 

Ich möchte:

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)); 

Gibt es etwas, das ich diese Arbeit zu machen tun könnte?

+2

Die Frage ist wohl jetzt „warum nicht“, sondern „warum doesn "t". Es könnte wahrscheinlich, aber es tut es nicht. –

+0

@NathanOliver Ich denke das würde eine gute Antwort geben. Würde es dir etwas ausmachen, zu posten? –

Antwort

5

Es gibt kein technisches Hindernis zu machen bind constexpr tun; zum Beispiel haben die Sprout C++ Libraries eine constexpr-enabled bind.

Jedoch implementations are not permitted to add constexpr to function signatures where it is not specified in the Standard, und es gab noch keinen Vorschlag, constexpr zu bind hinzuzufügen, die ich kenne (Which parts of the C++14 Standard Library could be and which parts will be made constexpr?). Es ist ziemlich unwahrscheinlich, dass man ausbleiben würde, da bindmostly superseded von Lambda-Ausdrücke, die als C 17 ++ automatisch constexpr:

constexpr auto sumB = [](int x, foo const& y) { return x + y.b(); }; 
+0

Das ist großartig, weil es meine tiefere Frage beantwortet, warum 'bind' Ergebnisse' constexpr' nicht bedeutet, wenn sie keine Captures wie lambdas machen können, sollte dies zur Kompilierzeit vollständig definierbar sein. –

3

Nun, wir wissen nicht, was std::bind zurückgibt. Es könnte wahrscheinlich gemacht werden, um zu arbeiten, aber es gibt nichts, das vorgeschrieben ist, damit es funktioniert (nichts ist definiert als constexpr in der Spezifikation std::bind).

Auf was Sie tun können, wenn Sie Zugriff auf C++ 17 haben, ist ein Lambda zu verwenden. In C++ 17 die operator() der Lambda wird constexpr standardmäßig markiert werden, so dass Sie so etwas wie

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

+0

'std :: bind' kann keine' std :: function' zurückgeben. – Yakk

+0

@Yakk Nun, TIL. Danke für die Information. Antwort wurde bearbeitet. – NathanOliver

+0

Wenn Sie wissen möchten, warum, muss der Rückgabewert von 'std :: bind 'einen templated' operator() ', * und * haben, der bestimmte Eigenschaften haben muss, wenn er an einen anderen Bind-Ausdruck übergeben wird; 'std :: function' hat keine dieser Eigenschaften. – Yakk

Verwandte Themen