在C ++中访问类型成员

时间:2018-10-25 14:54:25

标签: c++

给出一个容器,例如vector<int>

#include <vector>
using namespace std;
vector<int> v{1, 2, 3};

为什么访问iteratorconst_iterator这样的公共类型成员似乎很困难?据我了解,这些名称是类(不是对象)的一部分,必须通过::访问以指定范围,但是当v.const_iterator时有理由禁止v是已知的? 示例:

int f(v.iterator it) {
    return *it;
}
// or
int g(v::iterator it) {
    return *it;
}

一种解决方法是使用decltype,如下所示:

int h(decltype(v)::iterator it) {
    return *it;
}

但是这种方法甚至不能在类中使用,因为以下操作会失败:

class A
{
public:
    int h(decltype(x)::iterator it) {
        return *it;
    }
private:
    vector<int> x;
};

编辑

只需一点便笺。 如所指出的,v.iterator的含义将取决于使用时(编译时)v的类型,而忽略运行时多态性。但是对于静态类成员也是如此。 示例:

struct A
{
    static const int x = 1;
};
struct B : public A
{
    static const int x = 2;
};
void eval()
{
    B b;
    A& ar = b;
    b.x; // 2
    ar.x; // 1, even though ar refers to the same underlying object (by the base type)
}

2 个答案:

答案 0 :(得分:1)

正如@Slava在评论中指出的,decltype(x)是做到这一点的方法:

#include <vector>
using namespace std;
vector<int> v{1, 2, 3};
int f(decltype(v)::iterator it) {
    return *it;
}

int g(decltype(v)::iterator it) {
    return *it;
}

class A
{
private:
    vector<int> x;
public:
    int h(decltype(x)::iterator it) {
        return *it;
    }
};

成员访问权限.和范围解析操作符::可能不会过载。正如您可能从名称中推断出的那样,.用于access members,而::用于访问scope

#include <iostream>

struct B {
    class iterator { };

    // no need for typename, compiler knows that we mean typedef B::iterator, as he can only find it
    iterator iterator1;

    // member named the same as class, ops!
    int iterator;

    // we need to use typename here, B::iterator is resolved as member
    // iterator iteartor3;
    typename B::iterator iterator2;
};

int main() {
    B bobj;

    // we access the member iterator inside b
    bobj.iterator = 1;

    // we declare object of B::iterator type
    // we need to tell compiler that we want only types
    typename B::iterator iterator;

    // this will work too
    typename decltype(bobj)::iterator iterator2;

    // we declare a member pointer to the iterator member inside some B class
    // no typename, as I want pointer to member, not pointer to... type
    int B::* pointer = &B::iterator;

    // this is just a pointer to the iterator specifically in bobj class
    int * pointer2 = &bobj.iterator;

    // foo(bar) 
    bobj.*pointer = 1;

    // this will work as expected
    int decltype(bobj)::* pointer3 = &B::iterator;
}

此外,C ++中没有“类型成员”(至少我在C ++标准中找不到它们)。在类中声明为成员的类,枚举和typedefs声明称为“嵌套类型”或“嵌套类”。

答案 1 :(得分:0)

基本上,C ++允许您通过::访问值或类型。所以MyType::AnotherTypeMyType::AValue一样好。当您使用.遍历一个实例时,它仅表示它要解析一种符号,该符号是一种值(字段,函数等)。希望有帮助。