My process for Exercism’s exercises is this: I write everything in VSCode, test and troubleshoot it, then paste into the online editor, and try to interpret the CMake errors, if any. I’m using C++17 and g++13.
I’ve tried all the tests locally in VSCode and everything works without errors (except what’s expected from the tests, e.g. std::domain_error), and all of the expected results match the tests. When I submit it, I receive a million undefined reference errors (I included only a few lines, otherwise this post exceeds the character limit):
We received the following error when we ran your code:
/usr/lib/gcc/x86_64-alpine-linux-musl/12.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: CMakeFiles/circular-buffer.dir/circular_buffer_test.cpp.o: in function `CATCH2_INTERNAL_TEST_0()':
/tmp/circular-buffer/circular_buffer_test.cpp:16: undefined reference to `circular_buffer::circular_buffer<int>::read()'
/usr/lib/gcc/x86_64-alpine-linux-musl/12.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: CMakeFiles/circular-buffer.dir/circular_buffer_test.cpp.o: in function `CATCH2_INTERNAL_TEST_2()':
/tmp/circular-buffer/circular_buffer_test.cpp:24: undefined reference to `circular_buffer::circular_buffer<int>::write(int)'
/usr/lib/gcc/x86_64-alpine-linux-musl/12.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: /tmp/circular-buffer/circular_buffer_test.cpp:27: undefined reference to `circular_buffer::circular_buffer<int>::read()'
/usr/lib/gcc/x86_64-alpine-linux-musl/12.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: CMakeFiles/circular-buffer.dir/circular_buffer_test.cpp.o: in function `CATCH2_INTERNAL_TEST_4()':
/tmp/circular-buffer/circular_buffer_test.cpp:34: undefined reference to `circular_buffer::circular_buffer<int>::write(int)'
/usr/lib/gcc/x86_64-alpine-linux-musl/12.2.1/../../../../x86_64-alpine-linux-musl/bin/ld: /tmp/circular-buffer/circular_buffer_test.cpp:37: undefined reference to `circular_buffer::circular_buffer<int>::read()'
...
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/circular-buffer.dir/build.make:115: circular-buffer] Error 1
make[1]: *** [CMakeFiles/Makefile2:85: CMakeFiles/circular-buffer.dir/all] Error 2
make: *** [Makefile:91: all] Error 2
Here is my hpp [h file, not hpp, typo, see response below] file:
#pragma once
#include <stdexcept>
#include <string>
#include <vector>
namespace circular_buffer {
template <class T>
class circular_buffer {
private:
int size;
public:
circular_buffer(int s) {
size = s;
}
int current_size{0};
std::vector<T> buffer{};
T read(void);
void write(T);
void clear(void);
void overwrite(T);
};
} // namespace circular_buffer
here is the cpp file:
#include "circular_buffer.h"
namespace circular_buffer {
template <class T>
T circular_buffer<T>::read() {
T output;
if (circular_buffer::buffer.size() == 0) {
throw std::domain_error("");
} else {
output = circular_buffer::buffer[0];
circular_buffer::buffer.erase(circular_buffer::buffer.begin());
circular_buffer::current_size -= 1;
}
return output;
}
template <class T>
void circular_buffer<T>::write(T in_data) {
if (circular_buffer::current_size < circular_buffer::size) {
circular_buffer::buffer.emplace_back(in_data);
circular_buffer::current_size += 1;
} else {
throw std::domain_error("");
}
}
template <class T>
void circular_buffer<T>::clear(void) {
circular_buffer::buffer = {};
circular_buffer::current_size = 0;
}
template <class T>
void circular_buffer<T>::overwrite(T in_data) {
if (circular_buffer::current_size == int(circular_buffer::size)) {
circular_buffer::buffer.erase(circular_buffer::buffer.begin());
circular_buffer::buffer.emplace_back(in_data);
} else {
circular_buffer::buffer.emplace_back(in_data);
circular_buffer::current_size += 1;
}
}
} // namespace circular_buffer
As you can guess, I’m stuck, that’s why I’m asking for help. So, what am I doing wrong? And how can I avoid a similar situation in the future (works on VSCode but not with CMake and the online editor)? I’m not familiar with CMake at all, in case that wasn’t obvious.
Thanks for your time!