2016-11-02 13 views
10

私は旧式のVisual Studio 2008を使用しています(「あなたの問題があります」という問題を解決します)。これはVisual Studioの問題です。 http://rextester.com/XKFR77690 これは問題があるようですhttp://ideone.com/bhxMi0アサートでdynamic_castがエラーを引き起こします

を考えると、これらの構造体:assertマクロで

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

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

は、私がこれを行うことができます。

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

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

しかし、ときassertif -statementであると私はまったく同じコードを使用します。assert(dynamic_cast<Foo<pair<int, int>>*>(test) != NULL)私はエラーを取得する:

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

ちなみに私はCスタイルのキャストを使用してこの問題を解決することができますassert((Foo<pair<int, int>>*)(test) != NULL)をしかし、私は考えますC-Styleのキャストはstatic_castで、私が欲しくないのはdynamic_castではありません。

答えて

8

assertはマクロです。これは、C++のコンストラクトについて何も知らないプリプロセッサによって処理されます。だから、次のよう

dynamic_cast<Foo<pair<int 

int>>*>(test) != NULL 

その関数形式マクロの引数を覚えておいてください:

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

は、この場合には二つの引数を取る関数のようなマクロに展開コンマで区切られています。それはすべてのプリプロセッサが見るものです。したがって、このケースでは、assertが要求する1つの引数の代わりに2つの引数を参照します。

あなたのCスタイルのキャストバージョンは、括弧のためにコンマよりも優先度が高いため、動作します。 dynamic_castの周りにそれらを置くことも仕事を行います。

+0

Re: "answer below me" - SOはさまざまな要因によって回答を並べ替えますので、「下」と「上」が変更される可能性があります。今のところ、私はあなたの下に何の答えも見ませんが、私はそれの上に1つを見ます。 –

+0

@PeteBecker私は20秒間正しい言葉を探して、*以下が*私の最後の手段だった。 – DeiDei

+0

@DeiDei答えにリンクするだけ。 –

8

Yup:マクロは、最上位のカンマを引数セパレータとして扱います。最も簡単な修正は、問題のあるコードの前後に括弧を挿入することです:

あなたが好む場合
assert((dynamic_cast<Foo<pair<int, int>>*>(test)) != NULL) 

や、コンテンツ全体を囲む括弧:

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

問題のCスタイルのキャストがコンパイル理由がされCスタイルのキャストではなく、テンプレートコードをカッコで囲んでいるので、カンマはもはや最外層にはありません。

関連する問題