Domanda

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.

È stato utile?

Soluzione

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.

Altri suggerimenti

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/

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top