Wie zu tun static_assert mit Makros?
Habe ich versucht, dieser Vorschlag zu tun, eine statische behaupten, aber ich komme nicht auf einen Kompilierungsfehler, wenn ich es innerhalb einer Methode einer Vorlage.
Das Beispiel folgt :
#include <iostream>
#define STATIC_ASSERT(expr, msg) \
{ \
char STATIC_ASSERTION__##msg[(expr)?1:-1]; \
(void)STATIC_ASSERTION__##msg[0]; \
}
template <typename T >
class A
{
public:
int foo(const int k )
{
//does not work
STATIC_ASSERT( k > 9, error_msg );
return k+5;
}
};
int bar(const int k )
{
//works fine
//STATIC_ASSERT( k > 9, error_msg );
return k+5;
}
int main()
{
A<int> a;
const int v = 2;
std::cout<<a.foo(v)<<std::endl;
std::cout<<bar(v)<<std::endl;
//works fine
//STATIC_ASSERT( v > 9, error_msg );
}
Ich kompiliert es mit g++ 4.7.2, mit einer Warnung, dass VLAs nicht unterstützt c++ ISO :
g++ -Wall -g -std=c++98 -Wextra -pedantic gvh.cpp
So, warum die Zusammenstellung nicht scheitern, wenn die STATIC_ASSERT wird innerhalb der template-Methode? Gibt es einen Weg, um es scheitern?
HINWEIS : ich brauche ein c++98 (vielleicht sogar noch c++03) - Lösung, wenn möglich, nur mit Makros.
- Boost ist ein pre-C++11 static assert.
- Ja, ich bin mir bewusst, BOOST_STATIC_ASSERT, aber es nutzt SFINAE zu überprüfen.
- In den Antworten und vor da gibt es eine gute Beratung, auf die statische assert Mechanismen sind rund, aber im wesentlichen in Ihrer spezifischen Verwendung, die Sie versuchen zu behaupten, auf ein function-parameter - einfach, weil es
const int
bedeutet nicht, dass es compile-Zeit - Konstante, die nur bedeutet, dass die Funktion eine Kopie der runtime-argument und wird nicht zulassen, dass der genannte code, um es zu ändern. Sie müssen akzeptierenk
als template-parameter (entweder fürA
oder durchA::foo
einetemplate <int K>
oder vielleicht Geige mit C++11constexpr
, um die compile-Zeit überprüfen Sie erwartet haben.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Vor C++11, die ich normalerweise tun würde:
Können Sie auch einen Blick auf boost static assert. Aber es ist viel zu aufgebläht für meinen Geschmack. Es ist leicht zu machen die Dinge größer werden, wird es schwer, Sie zu machen, besser.
Betrachten Sie so etwas wie Boost.StaticAssert, obwohl, wenn, dass Sie nicht verfügbar ist, können Sie versuchen, die Definition einer Vorlage.
Obwohl, das hat den Nachteil, dass Sie nicht mit einer Meldung zugeordnet sein.
Nach ein bisschen Suche durch StackOverflow, ich stolperte über diese Frage, die hatte eine ähnliche Antwort auf meine, und eine Reihe von alternativen für die tut es ohne boost.
Dies ist im Grunde Maxim ' s Antwort mit ein wenig mehr bequeme Schnittstelle. Ich habe es genommen aus hier. Nette Sache über es ist, dass die Verwendung von templates verhindert, dass der Benutzer die übergabe eines nicht-compile-Zeit-Konstanten Wert, wie der Zustand ist.
Wenn Sie Anruf hinzufügen, um die Methode in Frage (einer.foo();), die statische assert schlägt fehl (nur dann ist die Methode kompiliert werden). Sie wissen, dass Sie sollten nicht statisch geltend machen, zur Laufzeit Werte wie "k" nehme ich an.
bar
genannt wird)Statische assertions arbeiten nur mit compile-Zeit-Konstante Ausdrücke.
k
ist nicht eine compile-time constant expression.Nicht-Typ template-Parameter compile-time-Konstanten-Ausdrücke während der template-Instanziierung, so können Sie passen Sie Ihren code so: