使用函数中的数据初始化C ++ const成员(MPI_comm_size / rank)

时间:2014-02-19 14:30:30

标签: c++ class const mpi initializer

我正在创建一个类来包装一些MPI通信功能,我用一个特定的MPI通信器构建。我希望这个类可以将秩和通信器大小作为常量成员变量。不幸的是,这些只能通过将指向int的指针传递给C函数来实现。

class Comm {
public:
    const int rank;
    const int size;
    Comm(MPI_Comm);
};

Comm::Comm(MPI_Comm c) {
    MPI_Comm_rank(c, &rank); //error: rank is const
}

有两种方法可以解决这个问题:

1)继承其他获取值

的类
class Initializer {
protected:
    int hiddenSize;
    int hiddenRank;
public:
    Initializer(MPI_Comm);
}

class Comm : private Initializer {
public:
    const int size;
    const int rank;
    Comm(MPI_Comm);
}

Initializer::Initializer(MPI_Comm c) {
    MPI_Comm_rank(c, &hiddenRank);
    MPI_Comm_size(c, &hiddenSize);
}

Comm::Comm(MPI_Comm c) : Initializer(c), rank(hiddenRank), size(hiddenSize) {}

2)仅通过函数调用

使成员可访问
class Comm {
private:
    int rank;
    int size;
public:
    Comm(MPI_Comm);
    int getRank();
    int getSize();
};

Comm::Comm(MPI_Comm c) {
    MPI_Comm_rank(c, &rank);
    MPI_Comm_size(c, &size);
}

int Comm::getRank() {
    return rank;
}

int Comm::getSize() {
    return size;
}

我想知道我是否错过了一种更优雅的方式来解决这个问题,以及两者的相对优缺点。

2 个答案:

答案 0 :(得分:1)

您应该在构造函数初始化列表

中初始化const个成员
class A {
    const int i;
    A(int c) : i(c) {
       ....
    }
};

如果需要使用复杂表达式初始化i,则可能需要具有静态成员函数。见http://www.learncpp.com/cpp-tutorial/101-constructor-initialization-lists/

答案 1 :(得分:1)

您可以编写包装函数来初始化初始化列表中的const成员。

class Comm {
public:
    const int rank;
    const int size;
    Comm(MPI_Comm) : rank(get_rank(c)), size(get_size(c)) {}

private:
    static int get_rank(MPI_Comm c) {
        int rank;
        MPI_Comm_rank(c, &rank);
        return rank;
    }
    // and likewise for size
};

这比使用仅在施工期间使用的“隐藏”成员膨胀物体更整洁;并且可能比具有访问器的私有变量更好,因为您可以在类的成员中强制执行const-correctness。