Pergunta

I'm creating a class at the moment to wrap some MPI communciation functions, which I construct with a particular MPI communicator. I'd like the class to have the rank and communicator size available as constant member variables. Unfortunately, these are only available by passing a pointer to an int into a C function.

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
}

Two approaches spring to mind to get around this:

1) Inherit from some other class that gets the values

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) Make the members accessible only by function calls

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;
}

I wonder if I've missed a more elegant way of approaching this, and what the relative merits and disadvantages are of the two.

Foi útil?

Solução

You could write wrapper functions to initialise const members in the initialiser list.

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
};

This would be tidier than bloating the object with "hidden" members used only during construction; and might be better than private variables with accessors since you can enforce const-correctness within the class's members.

Outras dicas

You should initialize const members in the constructor initializer list

class A {
    const int i;
    A(int c) : i(c) {
       ....
    }
};

you may need to have a static member function if you need to initialize i with a complex expression. See http://www.learncpp.com/cpp-tutorial/101-constructor-initialization-lists/

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top