c++ compiler error cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'

StackOverflow https://stackoverflow.com/questions/18994590

  •  29-06-2022
  •  | 
  •  

Hey Im getting an error I think has to do with copying ofstream variable from reading other posts and Ive tried to change

std::ofstream outfil;

to

std::ofstream & outfil;

but I get error

reference value "outfil" requires an initializer

the code is:

#include <algorithm>
#include <fstream>
#include <iostream>
#include <iterator>
#include <sstream>
#include <string>
#include <vector>
#include <cstdlib>

std::vector<double> GetValues_n(const std::vector<std::string>& src, int start, int end)
{
    std::vector<double> ret;
    for(int i = start; i <= end; ++i)
    {
        ret.push_back(std::strtod(src[i].c_str(), nullptr));
    }
    return ret;
}

std::vector<int> GetValues_c(const std::vector<std::string>& src, int start, int end)
{
    std::vector<int> ret;
    for(int i = start; i <= end; ++i)
    {
        ret.push_back(std::atoi(src[i].c_str()));
    }
    return ret;
}

std::vector<double> polycentre(const std::vector<double>&  x,const std::vector<double>&  y,size_t ID)
{
    std::vector<double> C(3, 0);
    std::vector<double> x1(x.size(),0);
    std::vector<double> y1(y.size(),0);
    size_t sizx = x.size();
    size_t sizy = y.size();
    if(sizy != sizx)
    {
        std::cerr << "polycentre inputs not equal length";
    }
    double x0 = x[0];
    double y0 = y[0];
    for(int aa = 1; aa < sizx; ++aa)
    {
        if(x[aa] < x0){x0 = x[aa];}
        if(y[aa] < y0){y0 = y[aa];}
    }
    double A = 0.0;
    double B = 0.0;
    for(size_t aa = 0; aa < sizx; ++aa)
    {
        x1[aa] = x[aa] - x0;
        y1[aa] = y[aa] - x0;
        if(aa != sizx-1)
        {
            A = A + (x1[aa]*y1[aa+1] - x1[aa+1]*y1[aa]);
            B = B + ((x1[aa]+x1[aa+1])*(x1[aa]*y1[aa-1]-x1[aa-1]*y1[aa]));
        }
        else if(aa == sizx-1)
        {
            A = A + (x1[aa] - y1[aa]);
            B = B + ((x1[aa]+1)*(x1[aa]*1-1*y1[aa]));
        }
    }
    A = A*0.5;
    C[0] = ID;
    C[1] = ((1/6/A)*B)+x0;
    C[2] = ((1/6/A)*B)+y0;
    return C;
}

template <typename T>

void PrintValues(const std::string& title, std::vector<std::vector<T>>& v, std::ofstream outfil)
{
    if(outfil.is_open())
    {
        outfil << "ID,X,Y,Z \n";
        std::cout << title << std::endl;
        for(size_t line = 0; line < v.size(); ++line)
        {
            for(size_t val = 0; val < v[line].size(); ++val)
            {
                std::cout << v[line][val] << " ";
                outfil << v[line][val] << ",";
            }
            outfil << "\n";
            std::cout << std::endl;
        }
        std::cout << std::endl;
    }
}

int main(int argc, char* argv[])
{

    std::ofstream & outfil;

    if (argc < 2)
    {
        std::cerr << argv[0] << " needs to get input file (2dm)" << std::endl;
    }

    else if (argc == 3)
    {
        outfil.open(argv[2]);
    }

    else
    {
        outfil.open(std::string(argv[1]) + ".csv");
    }

    std::vector<std::vector<std::string>> values;
    std::ifstream fin(argv[1]);

    for (std::string line; std::getline(fin, line); )
    {
        std::istringstream in(line);
        values.push_back(
                         std::vector<std::string>(std::istream_iterator<std::string>(in),
                                                  std::istream_iterator<std::string>()));
    }

    std::vector<std::vector<int>> cells;
    std::vector<std::vector<double>> nodes;

    for (size_t i = 0; i < values.size(); ++i)
    {
        if(values[i][0] == "E3T")
        {
            cells.push_back(GetValues_c(values[i], 1, 5));
        }
        else if(values[i][0] == "E4Q")
        {
            cells.push_back(GetValues_c(values[i], 1, 6));
        }
        else if(values[i][0] == "ND")
        {
            nodes.push_back(GetValues_n(values[i], 1, 4));
        }
    }

    std::vector<std::vector<double>> cell_centres;

    for (size_t aa = 0; aa < cells.size(); ++aa)
    {
        if(cells[aa].size() == 5)
        {
            std::vector<double> xs;
            xs.at(0) = nodes[cells[aa][1] - 1][1];
            xs.at(1) = nodes[cells[aa][2] - 1][1];
            xs.at(2) = nodes[cells[aa][3] - 1][1];
            std::vector<double> ys;
            ys.at(0) = nodes[cells[aa][1] - 1][2];
            ys.at(1) = nodes[cells[aa][2] - 1][2];
            ys.at(2) = nodes[cells[aa][3] - 1][2];
            cell_centres.push_back(polycentre(xs,ys,aa+1));
        }
        else if(cells[aa].size() == 6)
        {
            std::vector<double> xs;
            xs.at(0) = nodes[cells[aa][1] - 1][1];
            xs.at(1) = nodes[cells[aa][2] - 1][1];
            xs.at(2) = nodes[cells[aa][3] - 1][1];
            xs.at(3) = nodes[cells[aa][4] - 1][1];
            std::vector<double> ys;
            ys.at(0) = nodes[cells[aa][1] - 1][2];
            ys.at(1) = nodes[cells[aa][2] - 1][2];
            ys.at(2) = nodes[cells[aa][3] - 1][2];
            ys.at(3) = nodes[cells[aa][4] - 1][2];
            cell_centres.push_back(polycentre(xs,ys,aa+1));
        }
    }

    PrintValues("Cell Centres", cell_centres, outfil);
    //PrintValues("Cells", cells, outfil);
    //PrintValues("Nodes", nodes, outfil);

    return 0;
}

and the error is:

1>------ Build started: Project: cell_centres_v2, Configuration: Debug Win32 ------
1>  main.cpp
1>c:\users\********\documents\visual studio 2010\projects\cell_centres_v2\cell_centres_v2\main.cpp(43): warning C4018: '<' : signed/unsigned mismatch
1>c:\program files (x86)\microsoft visual studio 10.0\vc\include\fstream(1116): error C2248: 'std::basic_ios<_Elem,_Traits>::basic_ios' : cannot access private member declared in class 'std::basic_ios<_Elem,_Traits>'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>
1>          ]
1>          c:\program files (x86)\microsoft visual studio 10.0\vc\include\ios(176) : see declaration of 'std::basic_ios<_Elem,_Traits>::basic_ios'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>
1>          ]
1>          This diagnostic occurred in the compiler generated function 'std::basic_ofstream<_Elem,_Traits>::basic_ofstream(const std::basic_ofstream<_Elem,_Traits> &)'
1>          with
1>          [
1>              _Elem=char,
1>              _Traits=std::char_traits<char>
1>          ]
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Many thanks.

有帮助吗?

解决方案

void PrintValues(const std::string& title, std::vector<std::vector<T>>& v, std::ofstream outfil) takes a std::ofstream by value, that is, copying the actual argument you pass to it, but fstreams may not be copied, hence the error you get regarding the private base it has.

You got it right when you thought of references as a solution, but you missed the point where you should use it. The correct way to solve your problem is to take a std::ofstream by reference in PrintValues, to do that, simply change its declaration to the following

Your guess is correct, `void PrintValues(const std::string& title, std::vector<std::vector<T>>& v, std::ofstream& outfil)

其他提示

You need to understand what references are for first. A reference is like a permanent pointer to another variable that cannot be changed to refer to something else, and cannot be null. Since it can't be null, it makes no sense to declare a reference without saying what it refers to.

You can say

std::ofstream outfile_;
std::ofstream& outfil = outfile_;

if you're still interested in playing with references.

You are declaring outfil as a reference to an object of type std::ofstream with the following line in main:

std::ofstream & outfil;

References must be initialized upon declaration. Your solution is to declare outfil as:

std::ofstream outfil;

References must be initialized when they are created. There doesn't seem to be a use for references there anyway.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top