0

Context

So I have a parser which can parse many different types of objects. I parse one file per object type using a function that has this typing:

template <typename T> 
std::vector<T *> parseFeaturesfromFile(std::string)

And when creating an object World, I use this function like this (in the constructor of World):

const std::vector<C_type *> c_types = struct_parser.parseFeaturesfromFile<C_type>(file_path);

where c_typesis defined in the World as

const std::vector<C_type *> c_types;

Error

The following error has cause me headaches for the last few days:

undefined reference to `std::vector<C_type*, std::allocator<C_type*> > parser::parseFeaturesfromFile<C_type>(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >)'
collect2.exe: error: ld returned 1 exit status
mingw32-make[1]: *** [Makefile.Debug:123: debug/Project.exe] Error 1

So what happens, if I understand this correctly, is that this function which adds values to my c_types vector, has the extra type allocator<C_type*>.

This could be because the problem actually lies with me using template functions incorrectly or something, however, many google searches later, I haven't found anywhere online where the allocator suddenly appeared where it shouldn't have.

This problem also appeared when trying to parse the other objects, for which you can freely replace all definition of C_type with D_type.

Another weird thing to note is that the compiler does not give any errors of bad typing in the parser.cpp or parser.h files. No warnings either.

The parseFeatures itself has worked on one of the types before, and this should not be the issue. Also, a functional error in my code would not lead to an error like this, I think.

Context of functions giving the errors

Additional context of the functions will be provided here.


parser.cpp


template<typename T>
std::vector<T *> parser::parseFeaturesfromFile(std::string filepath)
{
    loadfile(filepath);
    std::vector<T *> features = parseFeatures<T>();
    return features;
}

This function uses parseFeatures: (The important part, imo, is where the elements are added to the vector via: features.push_back(feature);)

template<typename T>
std::vector<T *> parser::parseFeatures()
{
    // make empty list
    std::vector<T *> features;

    while (input) {
        // get line content
        std::string line;
        getline(input, line);

        // continue if line only has whitespace
        if (std::regex_match(line, match_result, regex_whitespace_line)) {
            continue;
        }

        // if feature header, append new feature
        if (std::regex_match(line, match_result, regex_feature_header)) {
            std::string base = match_result[1].str();
            if (base == "Logistics" || base == "Production" || base == "Decoration" || base == "Vehicle" || base == "Cargo") {
                T * feature = new T;
                features.push_back(feature);
            }
            else {
                throwParseError("Feature header");
            }
        }

        // if attribute, apply it to the latest mentioned feature
        if (std::regex_match(line, match_result, regex_attribute_andCo)) {
            if (match_result.size() == 3) { // 2 groups matched
                std::string base = match_result[1].str();
                std::string rest = match_result[2].str();

                // get value(s) for attribute
                if (base == "name") {
                    std::regex_match(rest, match_result, regex_string);
                    features.back()->name = QString::fromStdString(match_result[1].str());
                }
                else if (base == "price") {
                    std::regex_match(rest, match_result, regex_int);
                    features.back()->price = std::stoi(match_result[1].str());
                }
                else {
                    throwParseError("Attribute");
                }
            }
        }

        // end of file
        if (!input)
        {
          break;
        }

    }
    return features;
}

Related hardware/software

I use QT Creator IDE, kit: Desktop Qt 6.0.2 MinGW 64-bit.

YarrikV
  • 1
  • 2
  • and where is `C_type` defined? – Stefan Riedel Jun 23 '21 at 14:05
  • and is `const std::vector c_types;` a member of your `World` class? If yes, the line `const std::vector c_types = struct_parser.parseFeaturesfromFile(file_path);` is shadowing your member `c_types`. And please use `auto` ... – Stefan Riedel Jun 23 '21 at 14:08

0 Answers0