Constexpr Aufrufe in Templates
- 
					
					
					
					
 Ich spiele aktuell mit Templates und constexpr Funktionen herum. Ich möchte einem Kollegen, welcher auf einem älteren C Standard ist, die möglichen Überprüfungen zur Compile-Zeit zeigen. Folgender Code habe ich: #include <cstdio> #include <format> constexpr int CountFormatArgs(const std::string_view s) { int Count = 0; for (size_t i = 0; i + 1 < s.size(); i += 2) { if (s[i] == '{' && s[i + 1] == '}') Count++; } return Count; } template<typename T> constexpr int CountArgs(T t) { return 1; } template<typename T, typename... Rest> constexpr int CountArgs(T t, Rest... rest) { return CountArgs(rest...) + 1; } template<typename... Rest> constexpr void TestFormatString(const std::string_view s, Rest... rest) { constexpr int Count_1 = CountFormatArgs(s); constexpr int Count_2 = CountArgs(rest...); static_assert(Count_1 == Count_2, "Anzahl der Parameter stimmt nicht mit Formatstring überein!"); } int main(int argc, char const* argv[]) { static_assert(CountFormatArgs("{}{}{}") == 3, "CountFormatArgs funktioniert nicht richtig"); static_assert(CountArgs(1, 2, 'c') == 3, "CountArgs funktioniert nicht richtig"); //TestFormatString("{}{}{}", 1, 2, 'c'); return 0; }Führe ich den Code aus, so funktioniert dieser. Kommentiere ich jedoch die Zeile TestFormatStringwieder ein, so bekomme ich den Fehler "C2131: Der Ausdruck wurde nicht zu einer Konstanten ausgewertet"Was mache ich falsch? 
 
- 
					
					
					
					
 Du kannst kein static_assertin der FunktionTestFormatStringso verwenden, denn die Parameter müssen nicht zwangsläufig Konstanten sein (und damit dürfen auch die beiden Variablen nicht alsconstexprdeklariert werden). Werfe stattdessen eine Exception!Fehlerhafter Code (mit Compiler-Fehler!) Ansonsten s.a. Cannot use static_assert inside a constexpr function inside a constexpr object. 
 
- 
					
					
					
					
 Hi, man möge mich gerne korrigieren, aber soweit ich das sehe geht das so nicht (und wie anders weiß ich nicht), da eine constexpr-function auch nicht constexpr ausführbar sein kann; das static_assert aber immer und sicher constexpr sein muss. 
 
- 
					
					
					
					
 @Th69 sagte in Constexpr Aufrufe in Templates: Werfe stattdessen eine Exception! Cool, das funktioniert. Ich habe nun zwei funktionierende Lösungen gefunden: template<typename... Rest> constexpr bool TestFormatString_1(const std::string_view s, Rest... rest) { //constexpr int Count_1 = CountFormat(s); // darf ich so nicht machen int Count_1 = CountFormat(s); int Count_2 = CountArgs(rest...); return Count_1 == Count_2; } template<typename... Rest> constexpr void TestFormatString_2(const std::string_view s, Rest... rest) { int Count_1 = CountFormat(s); int Count_2 = CountArgs(rest...); if (Count_1 != Count_2) throw std::runtime_error("Anzahl der Parameter stimmt nicht mit Formatstring überein!"); } consteval void Test() { TestFormatString_2("{}{}{}", 1, 2, 'c'); } int main(int argc, char const* argv[]) { static_assert(CountFormat("{}{}{}") == 3, "CountFormat funktioniert nicht richtig"); static_assert(CountArgs(1, 2, 'c') == 3, "CountArgs funktioniert nicht richtig"); static_assert(TestFormatString_1("{}{}{}", 3, 2, 'c'), "Anzahl der Parameter stimmt nicht mit Formatstring überein!"); Test(); return 0; }Ändere ich die Anzahl der Parameter, speichere die Datei ab, so schlägt Visual Studio direkt an. Sehr schön. PS: 
 Wie schon gesagt das ist nur eine Spielerei.