1. ホーム
  2. c++

[解決済み] this->ポインタ変数で 'this' を定数式で使用できないエラー (C++)

2022-02-07 06:53:18

質問

このエラーメッセージが出るのですが、配列の引数が一定でなければならないからだとわかっているのですが、「this-> V;」をどうアレンジすれば一定になるのかがわかりません。どなたか教えてください。ポインタ変数の機能がプログラム全体でわかるように、ほとんどコードを提供しました。

// A class that represents an undirected graph
class Graph
{
int V;    // number of vertices
list<int> *adj;    // A dynamic array of adjacency lists
int *in;
public:
// Constructor and destructor
Graph(int V);
~Graph() { delete[] adj; delete[] in; }

// function to add an edge to graph
void addEdge(int v, int w) { adj[v].push_back(w);  (in[w])++; }

// Method to check if this graph is Eulerian or not
bool isEulerianCycle();

// Method to check if all non-zero degree vertices are connected
bool isSC();

// Function to do DFS starting from v. Used in isConnected();
void DFSUtil(int v, bool visited[]);

Graph getTranspose();
};

Graph::Graph(int V)
{
this->V = V;
adj = new list<int>[V];
in = new int[V];
for (int i = 0; i < V; i++)
    in[i] = 0;
}

/* This function returns true if the directed graph has an eulerian
cycle, otherwise returns false  */
bool Graph::isEulerianCycle()
{
// Check if all non-zero degree vertices are connected
if (isSC() == false)
    return false;

// Check if in degree and out degree of every vertex is same
for (int i = 0; i < V; i++)
    if (adj[i].size() != in[i])
        return false;

return true;
}

// A recursive function to do DFS starting from v
void Graph::DFSUtil(int v, bool visited[])
{
// Mark the current node as visited and print it
visited[v] = true;

// Recur for all the vertices adjacent to this vertex
list<int>::iterator i;
for (i = adj[v].begin(); i != adj[v].end(); ++i)
    if (!visited[*i])
        DFSUtil(*i, visited);
}

// Function that returns reverse (or transpose) of this graph
// This function is needed in isSC()
Graph Graph::getTranspose()
{
Graph g(V);
for (int v = 0; v < V; v++)
{
    // Recur for all the vertices adjacent to this vertex
    list<int>::iterator i;
    for (i = adj[v].begin(); i != adj[v].end(); ++i)
    {
        g.adj[*i].push_back(v);
        (g.in[v])++;
    }
}
return g;
}

// This function returns true if all non-zero degree vertices of 
// graph are strongly connected
bool Graph::isSC()
{
// Mark all the vertices as not visited (For first DFS)
bool visited[V]; // error: 'this' cannot be used in a constant expression
for (int i = 0; i < V; i++)
    visited[i] = false;

// Find the first vertex with non-zero degree
int n;
for (n = 0; n < V; n++)
    if (adj[n].size() > 0)
        break;

// Do DFS traversal starting from first non zero degree vertex.
DFSUtil(n, visited);

// If DFS traversal doesn't visit all vertices, then return false.
for (int i = 0; i < V; i++)
    if (adj[i].size() > 0 && visited[i] == false)
        return false;

// Create a reversed graph
Graph gr = getTranspose();

// Mark all the vertices as not visited (For second DFS)
for (int i = 0; i < V; i++)
    visited[i] = false;

// Do DFS for reversed graph starting from first vertex.
// Staring Vertex must be same starting point of first DFS
gr.DFSUtil(n, visited);

// If all vertices are not visited in second DFS, then
// return false
for (int i = 0; i < V; i++)
    if (adj[i].size() > 0 && visited[i] == false)
        return false;

return true;
}

解決方法は?

C++では、サイズが一定でない配列はサポートされていません。(非定数とは、コンパイル時に分からないものという意味です)。そのため、その行でエラーが発生します。

bool visited[V];

コードを書き直し、std コンテナ (std::vector, std::list) に固執してください。

class Graph
{
    int V;    // number of vertices
    vector<list<int>> adj;    // A dynamic array of adjacency lists
    vector<int> in;
    // etc...
    // and you can access the elements just like a normal array (in[3] = 5, etc...)

Graph::Graph(int V)
{
    this->V = V;
    adj.Resize(V);
    in.Resize(V);
    // etc

vector<bool> visited(V);

これで、コードを修正し、現在のエラーを克服するための良いスタートを切ることができると思います。

編集

class Graph
{
    vector<list<int>> adj;     // A dynamic array of adjacency lists
    vector<int> in;
public:
    Graph(int V);
    ~Graph() { }
    // function to add an edge to graph
    void addEdge(int v, int w) { adj[v].push_back(w);  (in[w])++; }
    // Method to check if this graph is Eulerian or not
    bool isEulerianCycle();
    // Method to check if all non-zero degree vertices are connected
    bool isSC();
    // Function to do DFS starting from v. Used in isConnected();
    void DFSUtil(int v, vector<bool>& visited);

    Graph getTranspose();
};

Graph::Graph(int V)
{
    adj.resize(V);
    in.resize(V, 0);
}

/* This function returns true if the directed graph has an eulerian
cycle, otherwise returns false  */
bool Graph::isEulerianCycle()
{
    // Check if all non-zero degree vertices are connected
    if (isSC() == false)
        return false;

    // Check if in degree and out degree of every vertex is same
    for (size_t i = 0; i < adj.size(); i++)
        if (adj[i].size() != in[i])
            return false;
    return true;
}

// A recursive function to do DFS starting from v
void Graph::DFSUtil(int v, vector<bool>& visited)
{
    // Mark the current node as visited and print it
    visited[v] = true;

    // Recur for all the vertices adjacent to this vertex
    for (auto i = adj[v].begin(); i != adj[v].end(); ++i)
        if (!visited[*i])
            DFSUtil(*i, visited);
}




Graph Graph::getTranspose()
{
    Graph g(adj.size());
    for (int v = 0; v < adj.size(); v++)
    {
        // Recur for all the vertices adjacent to this vertex
        //list<int>::iterator i;
        for (auto i = adj[v].begin(); i != adj[v].end(); ++i)
        {
            g.adj[*i].push_back(v);
            (g.in[v])++;
        }
    }
    return g;
}
// This function returns true if all non-zero degree vertices of 
// graph are strongly connected
bool Graph::isSC()
{
    // Mark all the vertices as not visited (For first DFS)
    vector<bool> visited(adj.size(), false);

    // Find the first vertex with non-zero degree
    int n;
    for (n = 0; n < adj.size(); n++)
        if (adj[n].size() > 0)
            break;

    // Do DFS traversal starting from first non zero degree vertex.
    DFSUtil(n, visited);

    // If DFS traversal doesn't visit all vertices, then return false.
    for (int i = 0; i < adj.size(); i++)
        if (adj[i].size() > 0 && visited[i] == false)
            return false;

    // Create a reversed graph
    Graph gr = getTranspose();

    // Mark all the vertices as not visited (For second DFS)
    visited.resize(visited.size(), false);

    // Do DFS for reversed graph starting from first vertex.
    // Staring Vertex must be same starting point of first DFS
    gr.DFSUtil(n, visited);

    // If all vertices are not visited in second DFS, then
    // return false
    for (int i = 0; i < adj.size(); i++)
        if (adj[i].size() > 0 && visited[i] == false)
            return false;

    return true;
}