To nieco szalone rozwiązanie.
Odkomentuj linię Const c; foo(c);
, a zobaczysz, że się nie skompiluje. To jest kompilacja asertywna.
Wymaga to variable length arrays i może innych rzeczy specyficznych dla kompilatora. Jestem na g ++ - 4.6.
Wielkość tablicy wynosi 0 lub -1, w zależności od tego, czy funkcja członkowska zwraca wartość 10. Tak więc, jeśli można ją obliczyć w czasie kompilacji, wówczas kompilacja zdaje sobie sprawę, że jest to tablica o zmiennej długości, a także ma rozmiar ujemny. Ujemny rozmiar pozwala mu narzekad. W przeciwnym razie przechodzi do konwencjonalnego dowodu.
Uwaga: Dostaję zrzut rdzenia z wersją środowiska wykonawczego zaraz po niepowodzeniu asercji środowiska wykonawczego. Być może nie podoba mi się próbowanie free
tablicy o rozmiarze ujemnym. Aktualizacja: Otrzymuję zrzuty pamięci z niepowodzeniem asercji, nawet int main() {assert (1==2);}
. Czy to normalne?
#include <iostream>
#include <cassert>
using namespace std;
struct Const {
constexpr int member_function() { return 9; }
};
struct Runtime {
int member_function() { return 9; }
};
template<typename T>
void foo(T t) {
if(0) { // so it doesn't actually run any code to malloc/free the vla
int z[(t.member_function()==10)-1]; // fails at compile-time if necessary
}
assert(t.member_function()==10);
}
int main() {
//Const c; foo(c);
Runtime r; foo(r);
}
Podobny do http://stackoverflow.com/q/11441302/560648. Nie jestem pewien, czy to dotyczy. –
http://stackoverflow.com/q/6939103/560648 jest bliżej, i [mówi, że odpowiedź brzmi "nie"] (http://stackoverflow.com/a/6941680/560648). –
[stackoverflow.com/questions/18648069](http://stackoverflow.com/questions/18648069/g-doesnt-compile-constexpr-function-with-assert-in-it) jest jeszcze bliżej i mówi "tak, ale " –