Was ist der Unterschied zwischen C ++ 0x-Konzepte und die Boost-Concept Check Library (BCCL)?

StackOverflow https://stackoverflow.com/questions/1352571

  •  20-09-2019
  •  | 
  •  

Frage

Konzepte machte nicht die C ++ 0x-Standard, aber Erhöhung bietet noch Die Boost Concept Check Library (BCCL) . Ich denke, dass BCCL nicht alles abdecken, die in die C gemeint war ++ 0x-Standard. Was ist der Unterschied zwischen BCCL und der vorgeschlagenen C ++ 0x Lösung?

War es hilfreich?

Lösung

Überprüfen der Template-Definition

Ein großer Unterschied der Konzepte zu diesen manuellen Lösungen ist, dass Konzepte der Definition einer Vorlage, damit seinen Typen-geprüft ohne etwas Besonderes zu tun. Das Konzept Check Bibliothek erlaubt nur die Verwendung von geprüft sein Typ. Beispiel:

template<typename InputIterator>
int distance(InputIterator a, InputIterator b) 
{ return b - a; }

Sie können nun diese Vorlage mit Konzept überprüft und Eigenschaften streuen, aber Sie werden nie einen Fehler nach dieser Vorlage zu schreiben - weil der Standard der Compiler Verzögerung ermöglicht die Vorlage bis Instanziierung kompilieren. Zur Überprüfung, müssen Sie „Urform“ Klassen, die genau diese Vorgänge enthalten schreiben, die von der Schnittstelle erforderlich sind, und sie dann künstlich instanziiert.

in der Dokumentation von BCCL Lesen, fand ich es schon die gemeinsamen Urformen wie „default konstruierbar“ enthält. Aber wenn Sie Ihre eigenen Konzepte zu schreiben, müssen Sie auch Ihre eigenen Vorbilder liefern, was nicht einfach ist (Sie müssen genau das finden, die minimale Funktionalität eine Art zu schaffen hat). Zum Beispiel, wenn Ihr Urbild einen operator- enthält, dann ist der Test der Vorlage mit dem (falschen) Urbild erfolgreich sein wird, obwohl die Konzepte nicht so einen Operator erforderlich.

Der abgelehnte Konzept Vorschlag schafft Vorbilder für Sie automatisch, basierend auf den Anforderungen, die festgelegt wurden und dass wurden implizierte (eine Zeigertyp T* in einem Parameter verwendet werden, die PointeeType Anforderung für T zum Beispiel bedeuten). Sie müssen nicht über diese Dinge kümmern müssen -. Außer natürlich, wenn Ihre Template-Definition einen Typfehler enthält

Überprüfen semantische Anforderungen

Betrachten Sie diesen Code, mit hypothetischen Konzept überprüft

template<ForwardIterator I>
void f(I a, I b) {
  // loop two times!
  loopOverAToB(a, b);
  loopOverAToB(a, b);
}

Das BCCL Handbuch sagt, dass semantische Anforderungen sind nicht überprüft. Nur Syntax Anforderung und Typen geprüft. Betrachten wir eine Vorwärts-Iterator: Dort wird die semantische Anforderung besteht, dass Sie es in Multi-Pass-Algorithmen verwenden. Syntax-Prüfung wird nur nicht in der Lage sein, diese Anforderung zu testen (darüber nachdenken, was passiert, wenn ein Strom Iterator zufällig, dass der Check passieren würde!)

In dem abgelehnten Vorschlag, Sie hatten ausdrücklich auto vor Konzept Definitionen setzen, um den Compiler-Flag Erfolg nach Syntax-Prüfung zu machen. Wenn auto nicht angegeben wurde, dann eine Art explizit ein Konzept Karte zu definieren, zu sagen hatte es dieses Konzept unterstützt. Ein Strom Iterator würde also nie eine ForwardIterator Prüfung bestehen genommen werden.

Syntax Remapping

Dies war ein weiteres Merkmal. Eine Vorlage wie

template<InputIterator I>
  requires OutputStreamable<I::value_type>
void f(I a, I b) {
  while(a != b) std::cout << *a++ << " ";
}

Kann wie die folgenden verwendet werden, wenn der Benutzer ein Konzept Karte zur Verfügung stellen würde, die den Compiler lehrt, wie eine ganze Zahl dereferenzieren und damit wie eine ganze Zahl erfüllt das InputIterator Konzept.

f(1, 10);

Dies ist der Vorteil einer Sprache-basierte Lösung, und kann nicht immer durch BCCL gelöst werden, glaube ich.

Konzept basiert Overloading

Auf einem schnelles Lesen von BCCL, kann ich auch nichts erkennen, dass dies geschehen kann. Ein Konzept Matching Scheitern scheinen einen harten Kompilierungsfehler zu verursachen. Der abgelehnte Vorschlag ermöglicht die folgende:

template<ForwardIterator I>
I::difference_type distance(I a, I b) {
  I::difference_type d = 0; while(a != b) ++a, ++d;
  return d;
}

template<RandomAccessIterator I>
I::difference_type distance(I a, I b) {
  return b - a;
}

Wenn ein Typ mit beiden Vorlagen verwendet werden könnte, dann wäre die zweite Vorlage verwendet werden, weil es mehr spezialisiert ist: RandomAccessIterator verfeinert das ForwardIterator Konzept.

Andere Tipps

Das C ++ 0x Konzept Merkmal wäre eine Kernsprachenfunktion , deren gesamten Prozess vom Compiler durchgeführt werden würde.

Die Boost-Konzept Bibliothek prüfen ist die fast gleiche Funktion, aber in C ++ geschrieben und Makro als Bibliothek einen Teil der Funktion zu simulieren. Es kann nicht alles tun, was in der letzten Sprache-Funktion erforderlich wäre (abhängig von der endgültigen Funktion Definition), aber einige äquivalenten Lösungen für Vorlagentypprüfung zur Verfügung stellen (und andere Kompilierung überprüft).

Wie bereits angedeutet, wie das C ++ 0x-Konzept ein Sprachfeature ist, würde es ermöglichen, elegantere semantische bereitzustellen und Compiler verwenden Informationen erlauben derzeit nicht zur Verfügung, um das Programm, so dass ausführlichere oder intelligente Fehler bei der Kompilierung (als das Konzept erste Ziel ist die abstrakte Typprüfung in Templates) zu ermöglichen.

Disclaimer: Ich war erfolgreich BCCL nicht in der Lage innerhalb der letzten 30 Minuten zu verwenden, obwohl ich hatte schon Boost-installiert. Das Beispiel sehen Sie unten sieht OK nach der BCCL Dokumentation Boost 1,37 aber hat nicht funktioniert. Ich denke, dies gilt als Nachteil.

Mit BCCL Sie nur so etwas wie statische Behauptungen erhalten, während die Kern Sprachkonzept Funktion voll modular Typprüfung bietet und in der Lage, einige Funktionsvorlage von der Teilnahme an der Überladungsauflösung zu verhindern. Mit nativer Konzepten kann der Körper von einer eingeschränkten Vorlage sofort vom Compiler überprüft werden, während BCCL nicht die Compiler Prüfung nichts in dieser Hinsicht machen. Sie müssen manuell die Vorlage mit „arche Typ“ Parametern instanziiert, um zu sehen, wenn die Vorlage keine Operationen verwendet, die nicht verfügbar sind (zum Beispiel operator-- auf Vorwärts Iteratoren).

Wie bei der Überladungsauflösung hier ein Beispiel:

template<typename Iter>
void foo(Iter,Iter) {
   BOOST_CONCEPT_ASSERT((RandomAccessIterator<Iter>));
}

void foo(long, int);

int main() {
   foo(2,3); // compile-time error
}

Die Vorlage ist ein besseres Spiel, weil das Nicht-Template zu lange eine Umwandlung von int erfordert. Aber Instanziierung schlägt fehl, weil int kein Iterator ist. Sie erhalten eine nette Fehlermeldung es zu erklären, aber die nicht sehr befriedigend ist, ist es? Mit nativer Konzepte haben Sie geschrieben konnten

template<typename Iter>
  requires RandomAccessIterator<Iter>
void foo(Iter,Iter) {}

void foo(long, int);

int main() {
   foo(2,3); // OK, picks non-template foo
}

die Funktion Vorlage Hier wird nicht an der Überladungsauflösung, weil die Voraussetzung für T = int nicht erfüllt ist. Great!

Wir bekommen immer noch zu constrain Funktionsschablonen mit dem SFINAE Trick. C ++ 0x erweitert SFINAE auf Ausdrücke und zusammen mit decltype und Standardvorlage Argumente für Funktionsschablonen können wir schreiben

template<typename T> T&& make();

template<typename Iter, class = decltype( *make<Iter>() )>
void foo(Iter,Iter) {}

void foo(long, int);

int main() {
   foo(2,3); // OK, picks non-template foo
}

In diesem Fall Vorlage Argument Abzug fehl leise , da der Compiler nicht weiß, was die Art des Ausdrucks * make () sein soll (wir können nicht dereferenzieren ein int). Mit etwas Metaprogrammierung und einige Makros können wir ziemlich nahe zur Einführung beliebigen strukturellen Beschränkungen auf Template-Parameter erhalten in lesbarer Weise . Hier ist, wie es unter der Annahme, entsprechende Definitionen aussehen könnte für BRAUCHT und RandomAccessIterator:

template <typename Iter
  REQUIRES( RandomAccessIterator<Iter> )
>
void foo(Iter,Iter) {}

HTH, S

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top