Mit auto und decltype, um eine Retouren-aus-Funktion in einer Vorlage gebildete Klasse

Wie kann ich mich zwingen, eine Funktion in eine vorgefertigte Klasse für die Rückgabe einer Referenz auf eine Membervariable mit auto/decltype?

Hier verharmlost Beispiel, was ich versuche zu tun. Angenommen, du hast eine vorgefertigte Klasse, die speichert etwas in eine private member-variable, a_ wie folgt:

#include <iostream>

template <typename T>
class A
{
private:
  T a_;

public:
  A(T a) : a_(a) {}

  //1. Return const reference to a_
  const T & get() const { return a_; }

  //2. Return non-const reference to a_
  T & get() { return a_; }
};

int main(int argc, char *argv[])
{
  A<int> a(3);

  const auto & a1 = a.get(); //1. Return const reference to a_
  //a1 = 4;  //Shouldn't compile
  std::cout << "Value of a = " << a.get() << std::endl;

  auto & a2 = a.get(); //2. Return non-const reference to a_
  a2 = 5;
  std::cout << "Value of a = " << a.get() << std::endl;

  return 0;
}

Die erwartete/gewünschte Ausgabe:

Value of a = 3
Value of a = 5

Aber nun, angenommen, ich möchte die compiler, Rückschlüsse auf die Art zurückgegeben, die von const und non-const get() Funktionen in A<T> und ich möchte sicherstellen, dass beide Aufrufe geben Referenzen zu a_.

Meine beste Vermutung ist derzeit:

template <typename T>
class A
{
private:
  T a_;

public:
  A(T a) : a_(a) {}

  //1. Return const reference to a_
  const auto get() const -> std::add_lvalue_reference<const decltype(a_)>::type
  {
    return a_;
  }

  //2. Return non-const reference to a_
  auto get() -> std::add_lvalue_reference<decltype(a_)>::type
  {
    return a_;
  }
};

aber, dass nicht kompiliert werden kann. Die ersten Fehler gegeben, die von GCC ist:

decltype.cpp:11:29: error: expected type-specifier
decltype.cpp:11:26: error: expected ‘;’ at end of member declaration
decltype.cpp:11:29: error: add_lvalue_reference in namespace std does not name a type

Die motivation für diese liegt außerhalb meiner destilliertem Beispiel-code, sondern ergibt sich aus einem Versuch, reduzieren die Anzahl der Parameter eine Vorlage nimmt, wenn eine (oder mehrere) dieser Parameter wird nur verwendet, um anzugeben, eine Rückkehr geben, die der compiler sollte (glaube ich) in der Lage sein, um daraus von selbst. Hinweis: in der realen Welt, ist der Rückgabetyp von get() ist nicht, dass der a_, aber ist der return-Typ von Funktion f(a_) was weiß ich zu sein, ableitbar durch den compiler. Daher mein Bedürfnis für auto/decltype in diesem Beispiel.

Die Sache, die mir rätselhaft ist, dass der compiler ableiten kann, ist der Rückgabetyp korrekt mit fast identischer code in einer nicht-Vorlagen-Klasse:

class A
{
private:
  int a_;

public:
  A(int a) : a_(a) {}

  //1. Return const reference to a_
  const auto get() const -> std::add_lvalue_reference<const decltype(a_)>::type
  {
    return a_;
  }

  //2. Return non-const reference to a_
  auto get() -> std::add_lvalue_reference<decltype(a_)>::type
  {
    return a_;
  }
};

Jede Hilfe zu verstehen, was mir fehlt, sind sehr willkommen.

Details:

Centos 6.5
gcc (GCC) 4.7.2 20121015 (Red Hat 4.7.2-5)
  • Sie müssen typename
  • const auto get() const Für eine trailing-return-Typ, verwenden Sie nur auto vor den Funktionsnamen, nicht const auto.
  • Sind Sie sicher? Es funktioniert, wenn ich hinzufügen typename wo Sie benötigt wird.
  • Das ist es, was das Geräusch erklärt. Ich kann schauen die Grammatik..
  • Sieht aus wie dyp ist korrekt - [dcl.spec.auto] Die auto und decltype(auto) Typ-Spezifizierer bestimmt eine Art Platzhalter, die ersetzt werden, später, entweder direkt oder durch Abzug von einer Initialisierung oder durch explizite Angabe mit einem trailing-return-Typ. Beide gcc und VS2013 akzeptieren const auto ohne Beschwerden obwohl.
  • Ich denke, dass der Absatz nicht direkt verbieten, mit const auto, denn es gilt auch für Deklarationen von Variablen (auto ersetzt wird). Achten Sie jedoch auf [dcl.fct]/2, die es verbietet ausdrücklich
  • 8.3.5[dcl.fct]/p2 sagt: "In einer Erklärung T D wo D hat die form [Grammatik für die Funktionsdeklaration mit trailing return type] T werden die einzelnen type-specifier auto."
  • Genau. Etwas Zeit für die bug-reports.
  • und dyp: ja, ich lese die gleiche Sache. Aber was ist abgeleitet Deklarator-Typ-Liste? 🙂
  • Ähhh wenn ich mich Recht erinnere ist dies definiert jedes mal, wenn es erwähnt wird (D. H., es ist eine sinnlose transparente alias)
  • stackoverflow.com/questions/13779273/...
  • Ich hätte erwartet [dcl.spec.auto] zu sagen, Optional cv-qualifiziert, wenn es erlaubt war, sich dann aber wieder die Sektion wies darauf hin, von TC nicht sagen nichts über decltype(auto) es könnte also ein Fehler sein.
  • Danke.
  • Gut [dcl.spec.auto] nicht implizit erlauben Lebenslauf-Qualifikationen; [dcl.fct]/2 erfordert die Verwendung eines trailing-return-Typ, der kann nicht kombiniert werden mit decltype(auto).
  • BTW // 1. Return const reference to a_ ist falsch, es gibt einen Verweis auf a_ die gebunden ist in eine const-Referenz.
  • Als Klarstellung für alle Besucher, die const auto ist es nicht notwendig, in diesem Zusammenhang ohnehin, anders als bei Variablen-Deklarationen mit auto -, Funktions-auto hat halten cv-Qualifikation.

InformationsquelleAutor duncan | 2014-07-13
Schreibe einen Kommentar