2016-06-14 18 views
15

In C++ Sie Mitglieder die folgende Art und Weise definieren:C++ alternatives Mitglied Definition

struct test { 
    using memberType = int(int); 
    /*virtual*/ memberType member; 
}; 

int test::member(int x) { return x; } 

Mit 14 C++ ist es eine Möglichkeit, das Element innerhalb der Klassendefinition zu definieren, zum Beispiel mit einem Lambda?

+2

Was ist der Nutzen von der Art ist, alias? Sie haben bereits festgestellt, dass dies die Fähigkeit einschränkt, das Mitglied in der Klasse zu definieren. – chris

+0

@chris vielleicht will er es als Typ für 'std :: function' verwenden? –

+2

Ich erkunde gerade die dunklen Ecken des C++ Standards, um neue Wege zu finden, generischen Code zu schreiben – Gaetano

Antwort

7

Ich glaube nicht, dass das möglich ist, aber man kann es tun, wenn das Mitglied ein Zeiger

struct test { 
    int (*member)(int) = [](int x){return x;}; 
}; 

seit einem Lambda mit einer leeren Aufnahmeliste funktioniert tatsächlich eine reguläre Funktion

+4

Und Sie können auch Ihren Alias ​​beibehalten, wenn Sie ihn in 'using memberType = int (*) (int);' ändern – Smeeheey

1

Die nur so konnte ich von uns denken, ein std::function<> Objekt zu verwenden, aber Sie müssen die Instanz zu übergeben (kann nicht denken, wie es automatisch gebunden werden konnte ..)

struct foo { 
    using T = int(foo&, int); 

    int b; 
    std::function<T> x = [](foo& f, int a) { return a * f.b; }; 
}; 
1

Sie suchen nach so etwas schreiben:

struct test { 
    auto member_impl = [this]() { 
    }; 
}; 

Dies schlägt auf (mindestens) drei Punkte:

  1. Sie keine nicht-statisches Element auto erklären kann.

  2. Sie können nicht den Typ eines Lambda-Namen (so muss es sein Auto)

  3. this ist zum Zeitpunkt der Definition der Klasse nicht zur Verfügung.

Kurze Antwort, nein.

aber man kann schreiben:

struct test { 
    auto member_impl() { 
    }; 
}; 

, die etwa so kurz wie es geht.

1

ich 5.1.5/3 erraten ist, was Sie verhindert, dass ein Lambda die Art und Weise verwenden Sie es benutzen würden, tut mir leid:

[...] Ein Lambda-Ausdruck ist nicht in einem unevaluierten Operanden auftreten (Klausel [expr]), in einem Template-Argument, in einer Alias-Deklaration, in einer typedef-Deklaration oder in der Deklaration einer Funktion oder Funktionsvorlage außerhalb ihres Funktionskörpers und Standardargumenten. [Hinweis: Es soll verhindert werden, dass Lambdas in einer Signatur erscheinen. - Endnote] [...]

Das heißt, C++ 14 ist können Sie einen Elementtyp definieren Vorlagen verwenden, wie im folgenden Beispiel:

template<typename F> 
struct S; 

template<typename R, typename... Args> 
struct S<R(Args...)> { 
    using member = R(Args...); 
    R operator()(Args...) { return R{}; } 
    member M; 
}; 

template<typename R, typename... Args> 
R S<R(Args...)>::M(Args...) { return R{}; } 

int main() { S<void(int)> s; }