Извинения за то, что не предоставили простой исполняемый код ошибки. Ошибка является частью большей кодовой базы, которая потребует большого количества рефакторинга.
У меня очень странная проблема с ссылками на код, которую я пока не могу решить.
У меня есть класс с static constexpr const char *
для некоторых строк и локальный std::sunique_ptr
. Указатель на другой шаблонный класс, который содержит другой шаблонный класс (# 2).
Основной класс такой (сокращенно):
class Manager {
public:
Manager();
virtual ~Manager();
private:
// Topic Constants
static constexpr const char* kActuatorsCommand = "ActuatorsCommand";
static constexpr const char* kActuatorsProxy = "ActuatorsProxy";
std::unique_ptr<DataReader> faults_;
};
Таким образом, конструктор DataReader
принимает два параметра const string &
.
Если я объявлю faults_
обычным старым указателем и создам его с помощью new
, код запускается и ссылки просто отлично: DataReader *faults_ = new DataReader<uint32_t>(kActuatorsCommand, kActuatorsProxy)
.
Однако, если я использую std::make_unique
, компоновщик жалуется, что существует неопределенная ссылка на эти строки static const char*
, даже если они находятся в заголовке класса.
Кроме того, если я удалю класс # 2, все будет нормально.
Использование gcc (Ubuntu 7.3.0-27ubuntu1~18.04) 7.3.0
Я понимаю, что это может быть довольно расплывчатый вопрос, но какое-то направление, куда смотреть, будет оценено.
Кроме того, этот вопрос может быть похож на этот . Однако в моем случае все находится на одном двоичном файле.
Обновление: наконец-то нашли, как его воспроизвести.
class DataReader {
public:
explicit DataReader(const std::string& topic, const std::string& library_name)
: topic_(topic),
library_name_(library_name) {
}
private:
const std::string name_;
const std::string topic_;
const std::string library_name_;
};
#include <memory>
#include "DataReader.h"
class Manager {
public:
Manager();
virtual ~Manager();
private:
// Topic Constants
static constexpr const char* kActuatorsCommand = "ActuatorsCommand";
static constexpr const char* kActuatorsProxy = "ActuatorsProxy";
std::unique_ptr<DataReader> faults_;
};
Manager::Manager() {
faults_ = std::make_unique<DataReader>(kActuatorsCommand, kActuatorsProxy);
}
Manager::~Manager() {}
Код не связывается при компиляции с -o0
. С -03
он нормально связывается.
g++ -O0 -Wall -Wconversion -lstdc++ -pthread -std=c++14 -o ex3 src/ex3.cpp
/tmp/ccJebZ18.o: In function `Manager::Manager()':
ex3.cpp:(.text+0x41): undefined reference to `Manager::kActuatorsProxy'
ex3.cpp:(.text+0x48): undefined reference to `Manager::kActuatorsCommand'
collect2: error: ld returned 1 exit status
Makefile:8: recipe for target 'ex3' failed