問題タブ [using-declaration]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - テンプレート `using` 宣言のこの使用法の問題点
using
次のテンプレート宣言の使い方の何が問題になっていますか?
gcc 4.8.2
不満:
c++ - 2 つのまったく同じ名前の名前検索で宣言を使用した場合の影響
基本的に、私の質問は名前の検索とusing
宣言に関連しています ( http://en.cppreference.com/w/cpp/language/namespace )。
次の (間違いなくばかげた) コードがあるとします。
したがって、私の理解では、両方の名前を表示する必要があり、名前の検索にはあいまいさが必要です。しかし、実際にはそうではありません。理由は何ですか、つまり、いくつかの概念を誤解していますか?
templates - Using宣言は、Dの基底クラス(エイリアス)であるCを参照していますが、有効とは認識されていません
これは clang の問題のように見えます (私は既にclang にバグをオープンしました) が、間違いを犯していないことを確認したいと思います。
次のコードを検討してください。
行 (2) ((1) と (4) がコメント化されている場合) および (3) ((4) がコメント化されている場合) は期待どおりに動作しますが、(1) (上記の例をそのまま) を実行すると、次のエラーが発生します。
11 : エラー:
C::D を使用して 'typename' のない型に解決された依存型 using 宣言。[...]
11 : エラー: using 宣言が 'C::' を参照していますが、これは
C::D を使用する 'D' の基本クラスではありません。
とにかく、C
は のエイリアスでありD<U, A...>
、 の基底クラスですD<T, U, A...>
。
私の知る限り、そのスニペットはコンパイルされるはずです。私が間違っている?
c++ - 複数の仮想継承関数から選択する「using」キーワード
他の 2 つのクラス ('TestA' と 'TestB') から派生したクラス ('TestC') があります。どちらも同じ署名を持つ仮想関数を持っています。
「TestC」を介して関数にアクセスできるようにするには、使用するバージョンを指定する必要があります。「TestC」で関数を明示的に上書きし、必要なバージョンを呼び出すと、これは機能します。
出力: "bb"
それが期待される結果です。ただし、関数を明示的に上書きする代わりに「using」キーワードを使用すると、予期しない動作が発生することに気付きました。
(他は同じです)
出力: "ab"
誰かが私にこれを説明できますか?「テスト」が突然仮想ではなくなったように見えますか? 関数を明示的に上書きせずにこれを行う方法はありますか? (「オーバーライドを使用する」のようなもの)
c++ - using 宣言の奇妙な動作
次のコードを見てください
gcc 6.1、clang 3.8 、および msvc 2015 update 3 のすべては、これをコンパイルすることを拒否A
します。gcc はのデフォルト コンストラクタを参照しているようです。msvc と clang はそうではないようです。C
A
B
A
using base_type = A
A
おそらく、コンパイル エラーは、継承によってトリガーされた名前の挿入が原因である可能性があります (すべてのコンパイラが正常に動作するように変更using base_type = A
するため)。using base_type = ::A
より具体的には、
- 私が理解したように、 のよう
A::type
に、A
は単なるクラス名 (gcc はそれを関数名と誤解しますが) であり、C
内部A
ではなく、またはに導入されB
ます。この名前が のプライベートと見なされるのはなぜB
ですか? - このコンパイル エラーはバグと見なすべきですか、それとも標準の仕様の特殊なケースですか?
c++ - 名前空間でディレクティブを使用することによって発生するエラーの例
using
名前空間に宣言を含めると、どのようなエラーが発生する可能性があるかを理解しようとしています。これらの リンクを考慮しています。
using
宣言の使用により、名前が別のファイルの前にロードされているヘッダー ファイルに静かに置き換えられることによってエラーが発生する例を作成しようとしています。
ここで私は定義していMyProject::vector
ます:
これは「悪い」ヘッダーです: ここでは、 insideusing
の他の可能な定義を隠すようにだまそうとしています:vector
MyNamespace
MyProject::vector
これは、で定義されているように使用しようとしている無防備なヘッダーbase.h
です。
x.h
最後に、 と の両方を含む実装ファイルを次に示しますz.h
。
inをインクルードusing std::vector
すると、実際のコンパイル エラーが発生し、 inx.h
を使用するときにテンプレート引数を指定する必要があることが通知されます。これは、ヘッダー ファイルで宣言を使用してはならない理由の良い例ですか、それともこれよりも深く、もっと多くのことを見逃していますか?vector
z.h
x.h
vector
MyProject
using
ただし、に含めるusing namespace std
とx.h
、シャドウイングは発生せず、プログラムは問題なくコンパイルされます。何故ですか?を含むのusing namespace std
下に表示されているすべての名前をロードして、他の名前を隠してはいけませんか?std
vector
c++ - エイリアスの使用時に名前の競合が検出されない
これはこの質問のフォローアップです。次の例を検討してください。
ここで、コンパイラは の行でエラーを正しくスローし、前の定義に由来する の宣言がその名前空間に既に存在することusing Other::string
を訴えます。string
class string
これを考慮してください:
ここにはコンパイル エラーはありません。以前の の宣言を新しい宣言でシャドウすることに成功しましたstring
。
2 番目のケースでエラーが発生しないのはなぜですか? それ
using string = something
はエイリアスであり、実際の宣言は名前のためのものsomething
であり、コンパイラは実際の宣言間の競合のみを見つけることができるため、実際の宣言ではないためでしょうか。この場合、実際に and を宣言していると見なさsomething
れstring
ます。それでいいですか?これってかなり危険じゃないですか?つまり、プログラマーが気付かないうちにこれらのことが別々のヘッダーファイルで発生した場合、コンパイラーが何も言わずに、彼/彼が考えているものとはまったく異なる識別子を使用することになる可能性があります...