Anthony
Anthony

Reputation: 1133

C++ Unknown Symbol - Difficulty Finding Discrepancy Between .h and .cpp File

In my c++ program, I am getting this error:

Undefined symbols for architecture x86_64:
"MathExpression::layerFunctions", referenced from:
MathExpression::initializeLayerFunctions() in MathExpression.cpp.o
MathExpression::layer(MathExpression&, MathExpression::Operation, 
std::__1::vector<short, std::__1::allocator<short> >&) in 
MathExpression.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see 
invocation)
make[3]: *** [MathTestGenerator] Error 1
make[2]: *** [CMakeFiles/MathTestGenerator.dir/all] Error 2
make[1]: *** [CMakeFiles/MathTestGenerator.dir/rule] Error 2
make: *** [MathTestGenerator] Error 2

I have this declaration in my header file:

static std::vector<std::function<void(MathExpression &, std::vector<NumberType> &)>> layerFunctions;

In my .cpp file, I have:

std::vector<std::function<void(MathExpression &, std::vector<MathExpression::NumberType> &)>> layerFunctions(static_cast<MathExpression::OperationType> (MathExpression::Operation::EOE)); 

along with this function:

void MathExpression::initializeLayerFunctions() {
layerFunctions.resize(static_cast<OperationType>(Operation::EOE));

layerFunctions[static_cast<unsigned long>(Operation::addition)] = [] (MathExpression & exp, std::vector<NumberType> & otherArgs) -> void {
exp.string.insert(exp.string.end(), {' ', operationToChar(Operation::addition),    ' ', static_cast<CharType> 
(otherArgs[0])});
};

layerFunctions[static_cast<unsigned long>(Operation::subtraction)] = [] (MathExpression & exp, std::vector<NumberType> & otherArgs) -> void {
exp.string.insert(exp.string.end(), {' ', operationToChar(Operation::subtraction), ' ', static_cast<CharType> 
(otherArgs[0])});
};

layerFunctions[static_cast<unsigned long>(Operation::EOE)] = [] (MathExpression & exp, std::vector<NumberType> & otherArgs) -> void {
    // Throw or assert or something.
     };
}

I'm unsure as to what I could be doing wrong. As far as I can tell my declarations match up, but I can't get rid of the error. Would anyone have insight on how to solve this? Future thanks.

For reference, here are my header and .cpp files, respectively (bear in mind this is my first C++ program so I'm sure conventions are missing):

#ifndef MATHTESTGENERATOR_MATHEXPRESSION_H
#define MATHTESTGENERATOR_MATHEXPRESSION_H

#include <vector>
#include <functional>

class MathExpression {

public:
    using FieldType     = unsigned char;
    using OperationType = unsigned char;
    using NumberType    = short int;
    using CharType      = char;

    enum class Field : FieldType {
        integers,
        EOE // rational, real, complex.
    };

    enum class Operation : OperationType {
        addition,
        subtraction,
        EOE // multiplication, division, absolute value, radical
    };

    explicit MathExpression(std::vector<CharType>);
    std::vector<CharType> string;

    static void print(MathExpression &);
    static void layer(MathExpression &, Operation, 
    std::vector<NumberType> &);

    static void initialize();

    private:
    static char operationToChar(OperationType);
    static char operationToChar(Operation);

    static std::vector<std::function<void(MathExpression &, 
std::vector<NumberType> &)>> layerFunctions;
    static void initializeLayerFunctions();
};

#endif //MATHTESTGENERATOR_MATHEXPRESSION_H

and

#include "MathExpression.h"
#include <list>
#include <iostream>

std::vector<std::function<void(MathExpression &, 
std::vector<MathExpression::NumberType> &)>> 
layerFunctions(static_cast<MathExpression::OperationType>, (MathExpression::Operation::EOE));


void MathExpression::initialize() {
initializeLayerFunctions();
}

void MathExpression::initializeLayerFunctions() {
layerFunctions.resize(static_cast<OperationType>(Operation::EOE));

layerFunctions[static_cast<unsigned long>(Operation::addition)]    = [] (MathExpression & exp, std::vector<NumberType> & otherArgs) -> void { 
exp.string.insert(exp.string.end(), {' ', operationToChar(Operation::addition),    ' ', static_cast<CharType> 
(otherArgs[0])});
};

layerFunctions[static_cast<unsigned long>(Operation::subtraction)] = [] 
(MathExpression & exp, std::vector<NumberType> & otherArgs) -> void {
exp.string.insert(exp.string.end(), {' ', operationToChar(Operation::subtraction), ' ', static_cast<CharType> 
(otherArgs[0])});
};

layerFunctions[static_cast<unsigned long>(Operation::EOE)]         = [] (MathExpression & exp, std::vector<NumberType> & otherArgs) -> void {
// Throw or assert or something.
};
}

char MathExpression::operationToChar(OperationType ordinal) {
return operationToChar(static_cast<Operation>(ordinal));
}
char MathExpression::operationToChar(Operation op) {
switch(op) {
    case Operation::addition    : return '+';
    case Operation::subtraction : return '-';
    default                     : return '_';
}
}

MathExpression::MathExpression(std::vector<CharType> exp) {
this->string = std::vector<CharType>(exp);
}

void MathExpression::print(MathExpression &exp) {
for(int i = 0; i < exp.string.size(); i++) {
    std::cout << exp.string[i];
}
}

void MathExpression::layer(MathExpression &exp, 
MathExpression::Operation op, std::vector<NumberType> &otherArgs) {
layerFunctions[static_cast<OperationType>(op)](exp, otherArgs);
}

Upvotes: 0

Views: 484

Answers (1)

user9622872
user9622872

Reputation:

The issue lies within MathExpression.CPP. You defined layerFunctions, but since it is not within the MathExpressions namespace, I.E. MathExpressions::layerFunctions, it's saying that inside your header there is a linker error. By adding that namespace to your function declaration, your problem should cease to be a problem. You can find information about linker errors all over the place if you give them a quick google.

Upvotes: 1

Related Questions