Ich bin gespannt, ob es beim Kompilieren möglich ist, sicherzustellen, dass eine Methode an genau einer Stelle aufgerufen wird.
Beachten Sie, dass es in Ordnung ist, wenn die Funktion mehrmals aufgerufen wird (z. B. in einer Schleife). Sie sollte jedoch nicht in zwei separaten Schleifen aufgerufen werden.
Dies kann in zwei Teile unterteilt werden. Ich bin auch an Lösungen interessiert, die beide Teile abdecken:
(a) Sicherstellen, dass eine Methode an mindestens einer Stelle aufgerufen wird.
(B) Sicherstellen, dass eine Methode an höchstens einer Stelle aufgerufen wird
Ich habe die volle Kontrolle über die Struktur des Codes, und verschiedene Redewendungen, die dieselbe Idee erreichen, sind willkommen.
// class.h
class MyClass {
public:
void my_method();
}
Folgendes sollte nicht kompiliert werden (nie aufgerufen)
#include "class.h"
int main() {
MyClass my_class;
}
Folgendes sollte nicht kompiliert werden (an mehr als einer Stelle aufgerufen)
#include "class.h"
int main() {
MyClass my_class;
my_class.my_method();
while(true) {
my_class.my_method();
}
}
Folgendes sollte kompiliert werden (an genau einer Stelle aufgerufen):
#include "class.h"
int main() {
MyClass my_class;
while(true) {
my_class.my_method();
}
}
__COUNTER__
Makro verwenden. So etwas wiestatic_assert(__COUNTER__ == 0); my_class.my_method();
. Der Zähler wird jedoch in jeder Übersetzungseinheit zurückgesetzt, sodass Sie nur einmal überprüfen können, ob die Funktion pro Übersetzungseinheit aufgerufen wird.Antworten:
Low-Tech-Ansatz:
Da Sie die Kontrolle über die Codestruktur haben (einschließlich des Build-Systems, nehme ich an), ist hier eine Low-Tech-Lösung:
Alternative:
Wenn Sie es wirklich, wirklich, wirklich mit C ++ lösen möchten, können Sie es versuchen
Kompilierungszeitzähler sind jedoch schwarze Magie (sagt ich, und ich mag TMP wirklich), und das Erzwingen von ODR-Verstößen zu diesem Zweck scheint ein ähnliches Voodoo zu sein (zumindest würden Sie einen Testfall benötigen, der nicht verknüpft werden kann).
Aber ernsthaft:
Tu das nicht. Was auch immer Sie tun, es kann fast ohne Aufwand durch eine Wrapper-Funktion pervertiert werden:
MyClass::my_method()
wird nur im Wrapper aufgerufen. Alle anderen rufen nur den Wrapper auf, der wahrscheinlich sogar vom Compiler eingefügt wird.Wie andere vorgeschlagen haben: Es könnte viel hilfreicher sein, wenn Sie erklären würden, was Sie versuchen zu tun.
quelle
Hier ist eine grobe Idee, die möglicherweise funktioniert (zu lang für einen Kommentar - aber unvollständig für eine gute SO-Antwort).
Möglicherweise können Sie dies erreichen, indem Sie Vorlageninstanziierungen zählen / überprüfen.
Vorlagen werden nur bei Verwendung instanziiert .
In ähnlicher Weise werden Vorlagenmethoden- / Funktionskörper weder analysiert noch kompiliert oder verknüpft (über die Gewährleistung einer gültigen Syntax hinaus), wenn sie niemals aufgerufen werden. Dies bedeutet, dass keine Instanziierungen innerhalb ihres Körpers vorgenommen werden.
Möglicherweise können Sie eine Vorlage erstellen, die eine globale Anzahl von Instanziierungen und statische Zusicherungen beibehält (oder einen anderen TMP-Mechanismus, um frühere Instanziierungen zu überprüfen).
quelle
Es gibt eine Teillösung für diese Frage unter Verwendung des C-Präprozessors und der GNU-Inline-Baugruppe:
Header-Datei
a.h
:Implementierungsdatei
a.cc
:Diese Lösung ist insofern teilweise, als sie das Programm nicht daran hindert, die mit dem Unterstrich beginnende Methode direkt aufzurufen, ohne das Wrapper-Makro zu verwenden.
quelle
Verwenden Sie einen Constexpr-Zähler. Es gibt eine Implementierung in einer anderen Frage
quelle