David Ling
David Ling

Reputation: 145

C++ error: Variable does not name a type when attemtping to access global variables

Within a program i am writing i have 3 files. main, functions and a header file. The main file makes use of the header #include "implementation.cpp", and the function file makes use of the header #include "driver.h". Within the implementation file 3 structs have been declared, each sharing their values through the use of extern, too be seen in the minimal reproducing code required. Within the header file i have declared 3 variables to use these extern variables. I believed this was enough to fix my issue but problem still aries. When my code attempts to compile i recieve the following error messages. There are alot but I believe they all stem from the same issue. That issue being the header file able to locate the types Customer, Parts and Builder

In file included from implementation.cpp:8,
                 from driver.cpp:4:
driver.h:7:1: error: 'Customer' does not name a type
    7 | Customer myCustomer;
      | ^~~~~~~~
driver.h:8:1: error: 'Builder' does not name a type
    8 | Builder myBuilder;
      | ^~~~~~~
driver.h:9:1: error: 'Part' does not name a type
    9 | Part myPart;
      | ^~~~
driver.h:14:13: error: 'Part' was not declared in this scope
   14 | std::vector<Part> readpartFile();
      |             ^~~~
driver.h:14:17: error: template argument 1 is invalid
   14 | std::vector<Part> readpartFile();
      |                 ^
driver.h:14:17: error: template argument 2 is invalid
driver.h:16:13: error: 'Customer' was not declared in this scope
   16 | std::vector<Customer> readcustomerFile();
      |             ^~~~~~~~
driver.h:16:21: error: template argument 1 is invalid
   16 | std::vector<Customer> readcustomerFile();
      |                     ^
driver.h:16:21: error: template argument 2 is invalid
driver.h:18:13: error: 'Builder' was not declared in this scope
   18 | std::vector<Builder> readbuilderFile();
      |             ^~~~~~~
driver.h:18:20: error: template argument 1 is invalid
   18 | std::vector<Builder> readbuilderFile();
      |                    ^
driver.h:18:20: error: template argument 2 is invalid
driver.h:20:24: error: 'Customer' does not name a type
   20 | float complexity(const Customer& c, const std::vector<Part>& parts);
      |                        ^~~~~~~~
driver.h:20:55: error: 'Part' was not declared in this scope
   20 | float complexity(const Customer& c, const std::vector<Part>& parts);
      |                                                       ^~~~
driver.h:20:59: error: template argument 1 is invalid
   20 | float complexity(const Customer& c, const std::vector<Part>& parts);
      |                                                           ^
driver.h:20:59: error: template argument 2 is invalid
driver.h:22:40: error: 'Part' was not declared in this scope
   22 | void robotComplexity(const std::vector<Part>& vecB, const std::vector<Customer>& vecC);
      |                                        ^~~~
driver.h:22:44: error: template argument 1 is invalid
   22 | void robotComplexity(const std::vector<Part>& vecB, const std::vector<Customer>& vecC);
      |                                            ^
driver.h:22:44: error: template argument 2 is invalid
driver.h:22:71: error: 'Customer' was not declared in this scope
   22 | void robotComplexity(const std::vector<Part>& vecB, const std::vector<Customer>& vecC);
      |                                                                       ^~~~~~~~
driver.h:22:79: error: template argument 1 is invalid
   22 | void robotComplexity(const std::vector<Part>& vecB, const std::vector<Customer>& vecC);
      |                                                                               ^
driver.h:22:79: error: template argument 2 is invalid
driver.h:24:38: error: 'Customer' was not declared in this scope
   24 | double variability(const std::vector<Customer>& customerList, const std::vector<Builder>& builderList);
      |                                      ^~~~~~~~
driver.h:24:46: error: template argument 1 is invalid
   24 | double variability(const std::vector<Customer>& customerList, const std::vector<Builder>& builderList);
      |                                              ^
driver.h:24:46: error: template argument 2 is invalid
driver.h:24:81: error: 'Builder' was not declared in this scope
   24 | double variability(const std::vector<Customer>& customerList, const std::vector<Builder>& builderList);
      |                                                                                 ^~~~~~~
driver.h:24:88: error: template argument 1 is invalid
   24 | double variability(const std::vector<Customer>& customerList, const std::vector<Builder>& builderList);
      |                                                                                        ^
driver.h:24:88: error: template argument 2 is invalid
driver.h:26:34: error: 'Builder' was not declared in this scope
   26 | std::vector<double> buildAttempt(Builder b, double variaiblity, double complexityRobot);
      |                                  ^~~~~~~
driver.h:26:45: error: expected primary-expression before 'double'
   26 | std::vector<double> buildAttempt(Builder b, double variaiblity, double complexityRobot);
      |                                             ^~~~~~
driver.h:26:65: error: expected primary-expression before 'double'
   26 | std::vector<double> buildAttempt(Builder b, double variaiblity, double complexityRobot);
      |                                                                 ^~~~~~
In file included from driver.cpp:4:
implementation.cpp:43:19: error: ambiguating new declaration of 'std::vector<Part> readpartFile()'
   43 | std::vector<Part> readpartFile() //function to read Builders, Customers and Parts text file
      |                   ^~~~~~~~~~~~
In file included from implementation.cpp:8,
                 from driver.cpp:4:
driver.h:14:19: note: old declaration 'int readpartFile()'
   14 | std::vector<Part> readpartFile();
      |                   ^~~~~~~~~~~~
In file included from driver.cpp:4:
implementation.cpp:77:23: error: ambiguating new declaration of 'std::vector<Customer> readcustomerFile()'
   77 | std::vector<Customer> readcustomerFile()
      |                       ^~~~~~~~~~~~~~~~
In file included from implementation.cpp:8,
                 from driver.cpp:4:
driver.h:16:23: note: old declaration 'int readcustomerFile()'
   16 | std::vector<Customer> readcustomerFile();
      |                       ^~~~~~~~~~~~~~~~
In file included from driver.cpp:4:
implementation.cpp:100:22: error: ambiguating new declaration of 'std::vector<Builder> readbuilderFile()'
  100 | std::vector<Builder> readbuilderFile()
      |                      ^~~~~~~~~~~~~~~
In file included from implementation.cpp:8,
                 from driver.cpp:4:
driver.h:18:22: note: old declaration 'int readbuilderFile()'
   18 | std::vector<Builder> readbuilderFile();
      |                      ^~~~~~~~~~~~~~~
In file included from driver.cpp:4:
implementation.cpp:208:81: error: 'std::vector<double> buildAttempt(Builder, double, double)' redeclared as different kind of entity
  208 | vector<double>buildAttempt(Builder b, double variaiblity, double complexityRobot) {
      |                                                                                 ^
In file included from implementation.cpp:8,
                 from driver.cpp:4:
driver.h:26:21: note: previous declaration 'std::vector<double> buildAttempt'
   26 | std::vector<double> buildAttempt(Builder b, double variaiblity, double complexityRobot);
      |                     ^~~~~~~~~~~~
In file included from driver.cpp:4:
implementation.cpp: In function 'std::vector<double> buildAttempt(Builder, double, double)':
implementation.cpp:230:23: error: no matching function for call to 'complexity(Customer&, int&)'
  230 |  complexity(c,partsVec);
      |                       ^
In file included from implementation.cpp:8,
                 from driver.cpp:4:
driver.h:20:7: note: candidate: 'float complexity(const int&, const int&)'
   20 | float complexity(const Customer& c, const std::vector<Part>& parts);
      |       ^~~~~~~~~~
driver.h:20:34: note:   no known conversion for argument 1 from 'Customer' to 'const int&'
   20 | float complexity(const Customer& c, const std::vector<Part>& parts);
      |                  ~~~~~~~~~~~~~~~~^
In file included from driver.cpp:4:
implementation.cpp:138:7: note: candidate: 'float complexity(const Customer&, const std::vector<Part>&)'
  138 | float complexity(const Customer& c, const std::vector<Part>& parts)
      |       ^~~~~~~~~~
implementation.cpp:138:62: note:   no known conversion for argument 2 from 'int' to 'const std::vector<Part>&'
  138 | float complexity(const Customer& c, const std::vector<Part>& parts)
      |                                     ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
implementation.cpp:243:23: error: no matching function for call to 'complexity(Customer&, int&)'
  243 |  complexity(c,partsVec);
      |                       ^
In file included from implementation.cpp:8,
                 from driver.cpp:4:
driver.h:20:7: note: candidate: 'float complexity(const int&, const int&)'
   20 | float complexity(const Customer& c, const std::vector<Part>& parts);
      |       ^~~~~~~~~~
driver.h:20:34: note:   no known conversion for argument 1 from 'Customer' to 'const int&'
   20 | float complexity(const Customer& c, const std::vector<Part>& parts);
      |                  ~~~~~~~~~~~~~~~~^
In file included from driver.cpp:4:
implementation.cpp:138:7: note: candidate: 'float complexity(const Customer&, const std::vector<Part>&)'
  138 | float complexity(const Customer& c, const std::vector<Part>& parts)
      |       ^~~~~~~~~~
implementation.cpp:138:62: note:   no known conversion for argument 2 from 'int' to 'const std::vector<Part>&'
  138 | float complexity(const Customer& c, const std::vector<Part>& parts)
      |                                     ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
driver.cpp: In function 'int main()':
driver.cpp:24:27: error: no matching function for call to 'complexity(Customer&, int&)'
   24 |     complexity(c, partsVec);
      |                           ^
In file included from implementation.cpp:8,
                 from driver.cpp:4:
driver.h:20:7: note: candidate: 'float complexity(const int&, const int&)'
   20 | float complexity(const Customer& c, const std::vector<Part>& parts);
      |       ^~~~~~~~~~
driver.h:20:34: note:   no known conversion for argument 1 from 'Customer' to 'const int&'
   20 | float complexity(const Customer& c, const std::vector<Part>& parts);
      |                  ~~~~~~~~~~~~~~~~^
In file included from driver.cpp:4:
implementation.cpp:138:7: note: candidate: 'float complexity(const Customer&, const std::vector<Part>&)'
  138 | float complexity(const Customer& c, const std::vector<Part>& parts)
      |       ^~~~~~~~~~
implementation.cpp:138:62: note:   no known conversion for argument 2 from 'int' to 'const std::vector<Part>&'
  138 | float complexity(const Customer& c, const std::vector<Part>& parts)
      |                                     ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~
driver.cpp:26:53: error: no matching function for call to 'complexity(Customer&, int&)'
   26 |     writeFile(buildAttempt(b, complexity(c, partsVec), variability(customerVec, builderVec)));
      |                                                     ^
In file included from implementation.cpp:8,
                 from driver.cpp:4:
driver.h:20:7: note: candidate: 'float complexity(const int&, const int&)'
   20 | float complexity(const Customer& c, const std::vector<Part>& parts);
      |       ^~~~~~~~~~
driver.h:20:34: note:   no known conversion for argument 1 from 'Customer' to 'const int&'
   20 | float complexity(const Customer& c, const std::vector<Part>& parts);
      |                  ~~~~~~~~~~~~~~~~^
In file included from driver.cpp:4:
implementation.cpp:138:7: note: candidate: 'float complexity(const Customer&, const std::vector<Part>&)'
  138 | float complexity(const Customer& c, const std::vector<Part>& parts)
      |       ^~~~~~~~~~
implementation.cpp:138:62: note:   no known conversion for argument 2 from 'int' to 'const std::vector<Part>&'
  138 | float complexity(const Customer& c, const std::vector<Part>& parts)
      |                                     ~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~

Below is the minimal amount of code needed to reproduce this error. For convience i am only going to include code relevent to Part, as the base code for customer and builder is the same

my main file


#include <iostream>
#include <string>
#include "implementation.cpp"
#include <fstream>
#include <vector> 
#include <random>
using namespace std;

int main()
{
    Part p;
    auto partsVec =  readpartFile();return 0;
}

my header file


#include <vector>
#include <string>
#ifndef SOME_UNIQUE_NAME_HERE
#define SOME_UNIQUE_NAME_HERE


std::vector<Part> readpartFile();

#endif

From this point it is noted that the program does not recongise Part myPart, therefore declaring the vector as type Part does not work. Due to this these errors occur.

driver.h:9:1: error: 'Part' does not name a type
    9 | Part myPart;
      | ^~~~
driver.h:14:13: error: 'Part' was not declared in this scope
   14 | std::vector<Part> readpartFile();
      |             ^~~~

Finally here is the implementation file with code relevent to Part

#include <iostream>
#include <string>
#include <sstream> 
#include <fstream>
#include <algorithm> 
#include "driver.h"
#include <random>
#include <vector>
#include <time.h>
using namespace std;

struct Part {
char partCode;
std::string partName;
int maximum;
int minimum;
int complexity;
};
extern Part myPart;

std::ifstream partsList("Parts.txt");


std::vector<Part> readpartFile() //function to read Builders, Customers and Parts text file
{
    std::vector<Part> parts;
    std::string line;

    while (std::getline(partsList, line))
    {
        line.pop_back(); //removing '.' at end of line
        std::string token;
        std::istringstream ss(line);
        Part part;

        std::getline(ss, token, ':');
        part.partCode = token[0];
        std::getline(ss, part.partName, ':');
        std::getline(ss, token, ':');
        part.minimum = std::stoi(token);
        std::getline(ss, token, ':');
        part.maximum = std::stoi(token);
        std::getline(ss, token, ':');
        part.complexity = std::stoi(token);
        parts.push_back(std::move(part));
    }

    return parts;
    }

This code shuould be enough to provide anyone with the means to find out my issue and possible rectify the issue. Thankyou

P.S it should be noted that I have tried putting my structs in my header file, which does not work.

Upvotes: 0

Views: 2138

Answers (3)

Ted Lyngmo
Ted Lyngmo

Reputation: 117298

Restructured.

driver.h

#ifndef DRIVER_H
#define DRIVER_H

#include <string>
#include <vector>

struct Part {                      // class definition
    char partCode;
    std::string partName;
    int maximum;
    int minimum;
    int complexity;
};

std::vector<Part> readpartFile();  // (extern) forward declaration of a function

#endif

implementation.cpp

// only include what you use:

#include "driver.h"

//#include <algorithm>  // why?
#include <fstream>
//#include <iostream>   // why?
//#include <random>     // why?
#include <sstream>
#include <string>
#include <vector>
//#include <time.h>     // why?

// using namespace std; // don't

std::vector<Part>
readpartFile() // function to read Builders, Customers and Parts text file
{
    std::ifstream partsList("Parts.txt"); // don't make this global
    std::vector<Part> parts;
    std::string line;

    while(std::getline(partsList, line)) {
        line.pop_back(); // removing '.' at end of line
        std::string token;
        std::istringstream ss(line);
        Part part;

        std::getline(ss, token, ':');
        part.partCode = token[0];
        std::getline(ss, part.partName, ':');
        std::getline(ss, token, ':');
        part.minimum = std::stoi(token);
        std::getline(ss, token, ':');
        part.maximum = std::stoi(token);
        std::getline(ss, token, ':');
        part.complexity = std::stoi(token);
        parts.push_back(std::move(part));
    }

    return parts;
}

main.cpp

#include "driver.h" // not implementation.cpp

// unused header files removed

int main() {
    Part p;
    auto partsVec = readpartFile();
}

Compile - no header files, only .cpp files:

g++ -Wall -Wextra -pedantic -pedantic-errors main.cpp implementation.cpp -o program

Upvotes: 1

john
john

Reputation: 87959

You header file should look like this

#ifndef SOME_UNIQUE_NAME_HERE
#define SOME_UNIQUE_NAME_HERE

#include <vector>
#include <string>

struct Part {
    char partCode;
    std::string partName;
    int maximum;
    int minimum;
    int complexity;

};
extern Part myPart;

std::vector<Part> readpartFile();

#endif

Your main file should look like this

#include <iostream>
#include <string>
#include <fstream>
#include <vector> 
#include <random>
#include "myheaderfile.h" // sorry I don't know what your header file is really called
using namespace std;

int main()
{
    Part p;
    auto partsVec =  readpartFile();return 0;
}

Your implementation file should look like this

#include <iostream>
#include <string>
#include <sstream> 
#include <fstream>
#include <algorithm> 
#include "myheaderfile.h" // sorry I don't know what your header file is really called
#include <random>
#include <vector>
#include <time.h>
using namespace std;

std::vector<Part> readpartFile() //function to read Builders, Customers and Parts text file
{
    std::ifstream partsList("Parts.txt");

    ...
}

Upvotes: 1

4386427
4386427

Reputation: 44274

Seems you have a number of misunderstandings in releation to what you put in cpp-files and what you put in header files.

But to start with - don't include cpp files! It's the header file that you shall include.

So do

#include "implementation.h"  // instead of implementation.cpp

The implementation.h must have the definition of the Part struct. So move it from the cpp file to the header file. Like:

implementation.h

#ifndef SOME_UNIQUE_NAME_HERE
#define SOME_UNIQUE_NAME_HERE

#include <vector>
#include <string>

struct Part {
    char partCode;
    std::string partName;
    int maximum;
    int minimum;
    int complexity;
};


std::vector<Part> readpartFile();

#endif

And then you include the header file in implementation.cpp

implementation.cpp

#include <iostream>
#include <string>
#include <sstream> 
#include <fstream>
#include <algorithm> 
#include "driver.h"
#include <random>
#include <vector>
#include <time.h>

#include "implementation.h"  // Notice

using namespace std;


std::vector<Part> readpartFile() 
{
    ...
}

and likewise you include it in other files that needs to use the struct Part

Upvotes: 0

Related Questions