2017-01-19 5 views
9

私は教えているクラスのC++ベースの割り当てをまとめています。私は、自分のプログラムのさまざまなところで電話してもらいたいと思っている学生に輸出している機能を持っています。グレーディング中に、それらのコールを傍受して、正しい時間に正しいことをしていることを確認できます。私はそのコードが提供されているスターターファイルで何もすることを望んでいないので、使用していない引き数についてのコンパイラーの警告を抑制するために、すべての引き数をvoidにキャストする一連のステートメントを含む本体を関数に与えた。その過程で、これまでに見たことのない珍しいコンパイルエラーが発生しました。このサイトを検索しても何の助けにもなりませんでした。あなたが見ることができるように、これらのほとんどはうまくコンパイルvoidへの異常なコンパイラのエラーキャスト?

void iDontUseMyArguments(int a, int b) { 
    (void) a; // Explicit cast to void - totally fine! 
    (void) b; 
} 

void iDontEither(int a, int b) { 
    (void) a, b; // Comma expression casted to void, though technically 
        // b isn't casted to void! 
} 

void norDoI(int a, int b) { 
    void(a, b); // ERROR! No idea why this isn't okay. 
} 

void meNeither(int a, int b) { 
    (void)(a, b); // Comma expression casted to void - totally fine! 
} 

void jumpOnBandwagon(int a, int b) { 
    void((a, b)); // Comma expression casted to void - totally fine! 
} 

エラーが最善this reduced test caseを例示することができます。問題はこの1つにあった:

void(a, b); 

これは、次のエラーをトリガ:

prog.cpp: In function 'void norDoI(int, int)': 
prog.cpp:11:11: error: expression list treated as compound expression in functional cast [-fpermissive] 
    void(a, b); 
     ^

私は、このエラーメッセージが発生したことがありませんので、私はこれが私に教えしようとしているかわからないんだけど。

ラインの背後にある意図

void(a, b); 

は、関数スタイルのキャストを使用してvoid型にキャストしabを含むコンマ式であることでした。あなたが見ることができるように、次のようにすべての作業をバリアント:

(void)(a, b); 
void((a, b)); 

私は、これはおそらくほとんどの難問の解析とは何かを持っており、これは宣言と解釈ばかり、私は取得しています特定のエラーがない疑いますこれにマッチするようです。

私の質問は以下の通りです:

  1. なぜ、正確に、このコードは、法的ではないでしょうか?
  2. コンパイラは私が何をしようとしていると思いますか?
  3. なぜ、これらの他のバリアントは合法的なのですか?
+1

教えを始める前にもっと多くのことを学ぶ必要があります。 – SergeyA

+3

@SergeyAどういう意味でしょう。誰が彼らはC++を教えると言います。 – NathanOliver

+0

@ NathanOliver、私はOPがC++を教えると確信しています。私が間違っているなら、私は恩赦を請う。私が正しいとすれば、これは私たちが学校で行っているプログラミング教育に関するすべての問題を意味します。 – SergeyA

答えて

7

struct S { 
    S(int, int) {} 
}; 

S(1, 2)の意味は?

回答:12という値からタイプSのオブジェクトを構築することを意味します。


この関数テンプレートを考える:

template <typename T> T f() { return T(1, 2); } 

T(1, 2)は何を意味するのでしょうか?

回答:それはあなたがTは、例えば最初の質問からタイプSであれば可能である、値12からタイプTのオブジェクトを構築することを意味します。


同じ関数テンプレートの場合、f<void>()はどういう意味ですか?

回答:12の2つの値から単一のvoid値を作成しようとします。単一値のみをvoidに変換できるため、これは失敗します。 Tvoidであることを起こるとき


void(1, 2)T(1, 2)は異なる何かを意味するのでしょうか?

回答:いいえ、まったく同じことを意味します。そのため、エラーです。

+0

それは完璧な意味合いがあります。だから、 'void((1,2))'が働く理由は、それが引数リストとして解析できず、コンマ演算子の使用として解析されなければならないということですか? – templatetypedef

+0

@templatetypedefかなり。標準の文法は少し違っていますが、実際にはあなたのコメントとほとんど同じです。 – hvd

0

コンパイラは関数名として型を使用しようとしていると思うので、エラーとなります。

他の例は、型キャスト... documentationを見てみると

+0

ちょうどコンパイラによって与えられたメッセージです。 http://stackoverflow.com/questions/4775781/what-is-the-difference-between-c-like-casting-functional-casting – Rama

+0

私はこれが問題の根本原因だとは思わないこのようなコンテキストで名前を入力します。ありがとう、しかし! – templatetypedef

3

ている私は、あなたが変換例ルール(#3)のいずれかに違反していると仮定:

この構造を考えると

If there are more than one expression in parentheses, new_type must be a class with a suitably declared constructor. This expression is a prvalue of type new_type designating a temporary (until C++17)whose result object is (since C++17) direct-initialized with expressions.

関連する問題