3

次のコードは違法です。

#include <vector>
#include <utility>

int main() {
    std::vector<std::pair<int, char> > v;
    v.push_back(v.value_type(0, 'a')); // *
}

* を変更する必要があります

v.push_back(decltype(v)::value_type(0, 'a'));

コードが機能するようにします。

* と記された行が許可されていないのはなぜですか? その論理的根拠の背後にある理由は何ですか?

4

3 に答える 3

8

.要するに、C には型と変数に個別の名前空間があるためです。つまり、この方法でメンバーと型の両方にアクセスするために使用できる場合、C++ のあいまいさのためにメンバーにアクセスできないシナリオを構築できることを意味します。また、名前空間規則を変更すると、正当な C コードとの互換性が失われます。

struct s1 { typedef int X; };
struct s2 { void X(); };
typedef struct s1 X;
struct s2 X;
int main() {
    X.X();
}

それで?文脈からは、XX が何であるべきかはわかりません。

そのため、言語では.andはメンバー関数呼び出しを指し、型を指します。::X.X()X::X

于 2013-11-11T14:15:51.023 に答える
2

vはオブジェクトであり、オブジェクトのメンバーであるかのようv.value_typeにアクセスしようとしています。インスタンスではなくクラスに属してvalue_typeいるため、これは正しくありません。value_type(ちなみに、typedef はコンパイル時に修正されるため、常にクラスに属します。つまり、異なるインスタンスが異なるコピーを持つことはできません。)

decltype(v)は object の基になるクラス タイプに解決されるvため、この場合はstd::vector<std::pair<int, char> >. 次に、スコープ演算子::を使用して、クラス アイテムにアクセスできるようにします。

.他の一部の言語では、メンバー アクセス演算子とクラス アクセス演算子 (および)を区別する必要はありません::。C++ には、主に C に関連する歴史的な理由から両方があります。

于 2013-11-11T14:23:33.267 に答える