0

私は、C++11 標準の §5.1.1/8 (87 ページ) の段落で、このステートメント (私の強調) を検証しようとしていました。

オプションでキーワード テンプレート (14.2) が続き、その後にそのクラス (9.2) またはその基本クラスのいずれかのメンバーの名前 (条項 10) が続く、クラスを示すネストされた名前指定子は、修飾 ID; 3.4.3.1 は、qualified-ids に現れるクラス メンバーの名前検索について説明しています。その結果がメンバーです。結果の型はメンバーの型です。結果は、メンバーが静的メンバー関数またはデータ メンバーの場合は左辺値、それ以外の場合は prvalueです。

次のスニペットを使用します。

#include <iostream>

namespace N {
    class A {
    public:
        int i;
        void f();
    };
}

int main()
{
    std::cout << &N::A::f << '\n';
    std::cout << &N::A::i << '\n';
}

clangこのコードをgccコンパイルしVS2013、メンバー関数の定義が必要fです。

3つともプリント

1
1

しかし、これらの数字がどこから来たのかわかりません。

実際の例

上で強調表示されている段落によると、式N::A::fは prvalue でfあり、静的メンバー関数ではありません。それにもかかわらず、コードでそのアドレスを取得することができました。

同時に、§5.3.1/3 には次のように書かれています (強調は私のものです):

単項 & 演算子の結果は、そのオペランドへのポインターです。オペランドは、左辺値または修飾 IDでなければなりません。オペランドが、型 T を持つクラス C の非静的メンバー m を指定する 修飾 IDである場合、結果の型は「型 T のクラス C のメンバーへのポインター」であり、C::m を指定する prvalue です。

これは、 qualified-idであるため、左辺値でもN::A::fそうでもないという印象を与えます。N::A::i

4

1 に答える 1

2

しかし、これらの数字がどこから来たのかわかりません。

メンバーへのポインターはポインターではありません。元の値を出力することはできませんoperator<<。最適で唯一の一致は、bool値を出力するものです。したがって、それらは に変換されbool(明らかに が得られますtrue)、出力は になり1ます。std::boolalpha出力を再度挿入して確認してください。

それにもかかわらず、コードでそのアドレスを取得することができました。

それはあなたにとってどのように驚きですか?この正確な構成を許可および説明する部分を引用しました。非静的メンバーを指定する修飾 ID のアドレスを取得すると、そのメンバーが指定されることが明確に示されています。

修飾された idは、左辺値または右辺値だけではありません。それは文脈に完全に依存します。そのメンバー クラスまたはそのサブクラスの外部から非静的メンバーを指定する場合、特定のオブジェクトではなく値 (または情報、つまり型とオフセット) を指定するため、それらは prvalue でなければなりません。 )。

于 2014-10-13T18:25:25.483 に答える