問題タブ [inheriting-constructors]
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++ - コンストラクターを継承した後の基本クラス名のルックアップ
次のコードを検討してください。
直観的に、このコードが有効であることは明らかであり、コンパイルされます (gcc と clang でテスト済み)。
ただし、標準の何が有効かを理解したいと思います。base
具体的には、 inの名前検索base foo()
が、継承されたコンストラクターではなく基本クラスの型を見つける方法を理解したいと思います。
これは、標準的な言葉遣いの私の分析であり、コンストラクターに解決される必要があることを示しています。おそらく間違っていると思いますが、どこが間違っているのかを理解したいと思います。
私はから始めました[class.member.lookup] p1
:
メンバー名のルックアップは、クラス スコープ内の名前 ( id-expression )の意味を決定します。[...] id-expression の場合、名前の検索は のクラス スコープで開始されます。
this
p7
名前検索の結果は次のとおりです。
f
[a class scope] 内の [a member name] の名前検索の結果は、 S(f, C)C
の宣言セットです。
私はこの手順に従っていることを試みておりC
、derived
inをf
使用しています。base
base foo()
「宣言セット」は次のように定義されていp3
ます。
S(f, C)と呼ばれるinのルックアップ セットは、2 つのコンポーネント セットで構成されます。[...]
f
C
f
p4
宣言セットに何が入るかを示します。
C
name の宣言が含まれている場合f
、宣言セットには、ルックアップが発生する言語構造の要件を満たすすべてのf
defined inの宣言が含まれます。C
using base::base
( )内の名前base
( f
)の宣言です。このパラグラフは、ルックアップが発生する言語構造の要件を宣言が満たさないことが何を意味するかの例を示していますが、このルックアップから除外されるものは何もありません。derived
C
using base::base
次に、宣言セット内のusing 宣言p3
がどのように処理されるかについて説明します。
宣言セットでは、使用宣言は、派生クラスのメンバーによって非表示またはオーバーライドされていない指定されたメンバーのセットに置き換えられます。
それで、どのメンバーがusing base::base
指定しますか?私には、それが次のように答えられているようです[class.qual] p2
:
関数名が無視されず、 nested-name-specifierが classを指定するルックアップでは
C
:
で検索したときに、ネストされた名前指定子の後に指定された名前
C
が、の注入されたクラス名であるC
場合、またはmember-declarationであるusing-declarationで、 nested-name-specifier の後に指定された名前が、 nested-name- specifierの最後のコンポーネントの識別子[...]と同じ場合
代わりに、名前は class のコンストラクターに名前を付けると見なされ
C
ます。
「関数名が無視されないルックアップ」の意味を明確にする脚注があります。
関数名が無視されるルックアップには、nested-name-specifier、evalated-type-specifier、またはbase-specifierに現れる名前が含まれます。
これらのどれも問題の名前検索には当てはまらないので、この段落が適用され、コンストラクターを指定していると私には思われますusing base::base
(継承コンストラクター宣言であることを考えると、これは直感的に予想されることでもあります)。
派生クラス スコープで (基本クラス コンストラクターを指定する) 宣言を見つけたので、次の手順を続けます[class.member.lookup] p4
。
結果の宣言セットが空でない場合、サブオブジェクト セットには
C
それ自体が含まれ、計算は完了します。
つまり、名前のルックアップは派生クラスのスコープで結果を見つけたので、基本クラスのスコープ ( injected-class-name base
が見つかる場所) の検索には進みません。[余談ですが、名前のルックアップが基本クラスのスコープに続いたとしても、コンストラクターと注入されたクラス名の間を明確にするものは何もありません]。
私の推論はどこが間違っていますか?
c++ - コンストラクターの継承 (GCC と clang は一致しません)
私はカスタマイズしようとしstd::function
ており、次のコードから始めています。
std::function
オブジェクトを取るコンストラクタstd::nullptr_t
が に継承されることを期待していますmy_function
。したがって、コードは正常にコンパイルされるはずです。GCC 5.2 (C++14) ではコードのコンパイルに問題はありませんが、clang 3.6 (C++14) では次のような非常に紛らわしいエラー メッセージが生成されました。
これはclangのバグですか、それとも私のコードが間違っているだけですか? (非常に幸いなことに) 後者が当てはまる場合、コードをどのように修正すればよいでしょうか?
c++ - デフォルトでコンストラクタ noexcept(true) を継承していますか?
ここで私はそれを見つけました:
継承コンストラクター [...] は、noexcept(false) である関数を呼び出す必要がない限り、デフォルトですべて noexcept(true) です。その場合、これらの関数は noexcept(false) です。
次の例では、継承されたコンストラクターが、基底クラスのようにnoexcept(true)
明示的に定義されているにもかかわらず、それ自体が呼び出されるnoexcept(false) である関数と見なされるということですか?noexcept(false)
c++ - using-declaration では、依存する名前はテンプレート置換後にコンストラクターにレンダリングできますか?
この例では:
T::X
X
のメンバーを参照する従属名ですT
。S<T>
でインスタンス化されている場合T = X
:
using 宣言は継承コンストラクタになりますか?
Clang はコードを拒否しますDEMOが、g++ はそれを受け入れます。
次のように書くと注意してください。
どちらのコンパイラもコードを受け入れ、継承コンストラクタとして扱います。using T::X
標準で継承コンストラクターになることは許可されていますか?
c++ - テンプレートクラスから継承し、そのコンストラクタを継承する
テンプレート クラスを継承し、"using" を使用してそのコンストラクターを継承したいと考えています。しかし、移動コンストラクターを呼び出すと、「一致するコンストラクターがありません」で失敗します
ビルド結果