2016-11-02 21 views
10

Używam przestarzałego Visual Studio 2008 (pozwól, że zaoszczędzę ci kłopotu "jest twój problem".) To wydaje się być problemem z Visual Studio: http://rextester.com/XKFR77690 To wydaje się być problemem z assert makro: http://ideone.com/bhxMi0dynamic_cast w asercie Błąd powodujący błąd

Biorąc pod uwagę te kodowanym:

struct base { virtual ~base() {} }; 

template <typename T> 
struct Foo : base { T foo; }; 

mogę to zrobić:

base* test = new Foo<pair<int, int>>; 

if(dynamic_cast<Foo<pair<int, int>>*>(test) != NULL) cout << "hello world\n"; 

Ale gdy używam dokładnie ten sam kod, jak jest w if -statement w assert: assert(dynamic_cast<Foo<pair<int, int>>*>(test) != NULL) pojawia się błąd:

warning C4002: too many actual parameters for macro assert
error C2143: syntax error : missing ',' before ')'

Nawiasem mówiąc można to naprawić za pomocą obsady C-style: assert((Foo<pair<int, int>>*)(test) != NULL) ale myślę że obsada stylu C zrobi static_cast, a nie dynamic_cast, której nie chcę.

Odpowiedz

8

assert to makro. Jest obsługiwany przez preprocesor, który nic nie wie o konstrukcjach C++. Więc, co następuje:

assert(dynamic_cast<Foo<pair<int, int>>*>(test) != NULL) 

rozszerza się do funkcji podobny makro biorąc dwa argumenty, które w tym przypadku są:

dynamic_cast<Foo<pair<int 

i

int>>*>(test) != NULL 

Pamiętaj, że działają podobny makro argumenty są oddzielone przecinkami. To wszystko widzi preprocesor. W tym przypadku widzi 2 argumenty zamiast 1 argumentu wymaganego przez assert.

Twoja wersja w stylu C działa nawiasem z powodu nawiasów, które mają wyższy priorytet niż przecinek. Umieszczenie ich wokół dynamic_cast również wykonuje tę pracę.

+0

Odp: "odpowiedz pode mnie" - WIĘC przeorganizowuje odpowiedzi w zależności od różnych czynników, więc "poniżej" i "powyżej" może się zmienić. W tej chwili na przykład nie widzę żadnej odpowiedzi poniżej twojej, ale widzę jedną nad nią. –

+0

@PeteBecker Spędziłem 20 sekund szukając właściwego słowa i * poniżej * było moim ostatnim kursem ... – DeiDei

+0

@DeiDei Po prostu połącz odpowiedź. –

8

Yup: makra traktują przecinki najwyższego poziomu jako separatory argumentów. Najprostszym rozwiązaniem jest umieścić nawiasy wokół kodu naruszającego:

assert((dynamic_cast<Foo<pair<int, int>>*>(test)) != NULL) 

albo, jeśli wolisz, nawiasy wokół całego treści:

assert((dynamic_cast<Foo<pair<int, int>>*>(test) != NULL)) 

Powodem oddanych C-styl w pytaniu kompiluje jest nie jest to rzutowanie w stylu C, ale umieszcza kod szablonu w nawiasach, aby przecinek nie znajdował się już na najbardziej zewnętrznym poziomie.

Powiązane problemy