Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

Questions regarding overloading ostream operator in C++

Eduardo_J__Sanchez_P
501 Views

Dear all,

Context: I am developing a C++ API implementing Mimetic Finite Differences. An important class I am developing is the staggered grid representing my discrete domain:

I am starting simple: one spatial dimension.

For that I have created the MTK's Logically Rectangular One-Dimensional Uniform Staggered Grid class, or MTK_LR1DUniStgGrd.

Issue: I want to overload the ostream operator (<<) so that I can intuitively print the spatial values defining my grid.

Here's my header file:

[cpp]class MTK_LR1DUniStgGrd: public MTK_LR1DUniGrd {

  friend ostream &operator<<(ostream &, const MTK_LR1DUniStgGrd &);

  public:
    MTK_LR1DUniStgGrd();
    MTK_LR1DUniStgGrd(MTK_Real, MTK_Real, int);
    virtual ~MTK_LR1DUniStgGrd();
    void prt_array();
    
  private:
    MTK_Node *values_;  //!< Collection of nodes.
    int num_cells_;     //!< Number of cell centers.
};[/cpp]

And this is the implementation in the source file:

[cpp]// An overloaded stream insertion operator cannot be a member function if we
// would like to invoke it with cout, e.g., cout << grid;
ostream& operator<<(ostream& output, const MTK_LR1DUniStgGrd& grid) {

  //! Variables: 1
  int ii; // Iterator.

  //! MTK Classes:
  MTK_Real aux_west_boundary;
  MTK_Real aux_east_boundary;
  MTK_Real aux_nodal_step_size;
  MTK_Real aux_value_sub_ii;

  //! Begin.
  //! Validation stage:
  if (grid.values_ == NULL) {
    cerr << "Staggered grid can not be printed at " <<  __LINE__ - 1 << endl;
    cerr << " of file " << __FILE__ << endl << flush;
    cerr << "MTK: Terminating execution..." << endl << flush;
    exit(EXIT_FAILURE);
  }

  //! Initialization stage:
  aux_west_boundary = MTK_LR1DGrd::west_boundary_node();
  aux_east_boundary = MTK_LR1DGrd::east_boundary_node();
  aux_nodal_step_size = MTK_LR1DUniGrd::nodal_step_size();

  output << "Staggered = [" << aux_west_boundary << ":" <<
    aux_nodal_step_size<< ":" << aux_east_boundary << "] = " << endl << endl;
  for (ii = 0; ii < (1 + grid.num_cells_ + 1); ii++) {
    aux_value_sub_ii = (grid.values_[ii]).value();
    output << setw(10) << aux_value_sub_ii << " ";
  }
  output << endl;

  return output;
}[/cpp]

However, when building, I am getting the following output:

[bash]icpc    -c -g -Iinclude -MMD -MP -MF build/Debug/Intel-Linux-x86/src/mtk_lr_1d_uni_stg_grd.o.d -o build/Debug/Intel-Linux-x86/src/mtk_lr_1d_uni_stg_grd.o src/mtk_lr_1d_uni_stg_grd.cc
src/mtk_lr_1d_uni_stg_grd.cc(73): error #308: member "mtk::MTK_LR1DUniStgGrd::values_" (declared at line 76 of "include/mtk_lr_1d_uni_stg_grd.h") is inaccessible
    if (grid.values_ == NULL) {
             ^

src/mtk_lr_1d_uni_stg_grd.cc(81): error: a nonstatic member reference must be relative to a specific object
    aux_west_boundary = MTK_LR1DGrd::west_boundary_node();
                        ^

src/mtk_lr_1d_uni_stg_grd.cc(82): error: a nonstatic member reference must be relative to a specific object
    aux_east_boundary = MTK_LR1DGrd::east_boundary_node();
                        ^

src/mtk_lr_1d_uni_stg_grd.cc(83): error: a nonstatic member reference must be relative to a specific object
    aux_nodal_step_size = MTK_LR1DUniGrd::nodal_step_size();
                          ^

src/mtk_lr_1d_uni_stg_grd.cc(87): error #308: member "mtk::MTK_LR1DUniStgGrd::num_cells_" (declared at line 77 of "include/mtk_lr_1d_uni_stg_grd.h") is inaccessible
    for (ii = 0; ii < (1 + grid.num_cells_ + 1); ii++) {
                                ^

src/mtk_lr_1d_uni_stg_grd.cc(88): error #308: member "mtk::MTK_LR1DUniStgGrd::values_" (declared at line 76 of "include/mtk_lr_1d_uni_stg_grd.h") is inaccessible
      aux_value_sub_ii = (grid.values_[ii]).value();
                               ^

compilation aborted for src/mtk_lr_1d_uni_stg_grd.cc (code 2)[/bash]

As it can be seen, there are two kinds of problems that I am getting:

  1. Those related to the fact that the private members of the grid cannot be accessed, and
  2. Those related to invoking the base class to extract the values that I need, which I do not understand, since I have a public method called prt_array, which uses this code, and works.

Any hints?

Thanks in advanced! :D

0 Kudos
4 Replies
SergeyKostrov
Valued Contributor II
501 Views
>>... >>aux_west_boundary = MTK_LR1DGrd::west_boundary_node(); >> I don't think that the assignment is possible without a C++ assignment operator or a copy non-default constructor of the MTK_Real class.
0 Kudos
Eduardo_J__Sanchez_P
501 Views

Sergey Kostrov wrote:

I don't think that the assignment is possible without a C++ assignment operator or a copy non-default constructor of the MTK_Real class.

Yes it can be done... you doubt arises from a naming problem, which I have solved.

Thanks.

0 Kudos
Eduardo_J__Sanchez_P
501 Views

Dear Sergey,

Yes it does. However, your doubt arises from a naming issue, which I have fixed.

Thanks.

0 Kudos
Eduardo_J__Sanchez_P
501 Views

In fact, I have solved this problem:

[cpp]ostream& mtk::operator<<(ostream& output, const MTK_LR1DUniStgGrd& grid)[/cpp]

I specified that the global definition was within the scope of the mtk namespace.

Thanks.

If I could, I would flag this thread as solved.

 

0 Kudos
Reply