【问题标题】:Usage of templated interfaces cause “Undefined reference to”模板化接口的使用导致“未定义的引用”
【发布时间】:2017-12-23 18:14:22
【问题描述】:

所以我得到以下编译错误:

CMakeFiles/moje.dir/src/main/cpp/main.cpp.o:(.rodata._ZTV10ReadWriterINSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEENS0_19basic_istringstreamIcS3_S4_EEE[_ZTV10ReadWriterINSt7__cxx1119basic_ostringstreamIcSt11char_traitsIcESaIcEEENS0_19basic_istringstreamIcS3_S4_EEE]+0x48): undefined reference to `Writer<std::__cxx11::basic_istringstream<char, std::char_traits<char>, std::allocator<char> > >::write(std::__cxx11::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >&)'
CMakeFiles/moje.dir/src/main/cpp/main.cpp.o:(.rodata._ZTV6WriterINSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEEE[_ZTV6WriterINSt7__cxx1119basic_istringstreamIcSt11char_traitsIcESaIcEEEE]+0x20): undefined reference to `Writer<std::__cxx11::basic_istringstream<char, std::char_traits<char>, std::allocator<char> > >::write(std::__cxx11::basic_istringstream<char, std::char_traits<char>, std::allocator<char> >&)'

实现如下:

作家.h

#ifndef WRITER_H
#define WRITER_H

template<typename T>
class Writer {
public:
    virtual ~Writer() {}
    virtual void write(T &in);
};
#endif /* WRITER_H */

阅读器.h

#ifndef READER_H
#define READER_H

template<typename T>
class Reader {
public:
    virtual ~Reader() {}
    virtual T read();
};
#endif /* READER_H */

ReadWriter.h

#ifndef READWRITER_H
#define READWRITER_H
#include "Reader.h"
#include "Writer.h"

template<typename R, typename W>
class ReadWriter : public Reader<R>, public Writer<W>{
public:
    virtual ~ReadWriter() {}
};
#endif /* READWRITER_H */

ConfigReadWriter.h

#ifndef CONFIGREADWRITER_H
#define CONFIGREADWRITER_H
#include "header/ReadWriter.h"

class ConfigReadWriter : public ReadWriter<std::ostringstream, std::istringstream> {
public:
    ConfigReadWriter(Config &config) : config_(config) {}
    ~ConfigReadWriter() {}

    std::ostringstream read() override {
        std::ostringstream ss("ConfigReadWriter::read");
        return ss;
    };

    void write(std::istringstream& in) override {
        std::cout << "ConfigReadWriter::write" << std::endl;
    }
private:
    Config& config_;
};
#endif /* CONFIGREADWRITER_H */

Main.cpp:

#include "header/config/Config.h"
#include "header/config/ConfigReadWriter.h"


int main() {
    std::string a = "1";
    Config config(1, a);
    ConfigReadWriter rw(config);
    return 0; 
}

我明白,通过将实现保留在标头中,我不应该出现未定义引用的错误。 更正了 write 方法中的实现以适应接口。 仍然有编译错误。阅读链接。

【问题讨论】:

标签: c++ templates generics interface compiler-errors


【解决方案1】:

请注意,您的实现提供了获取副本的 void write(std::istringstream) 方法,而未定义的引用用于获取诸如 void write(std::istringstream &amp;) 之类的引用的方法,您没有在基类 virtual void write(T &amp;in); 中实现。所以你应该用正确的签名更新实现:

virtual void write(T &in) = 0; // no implementation

...

void write(std::istringstream &) override    {
    std::cout << "ConfigReadWriter::write" << std::endl;
}

override 说明符确保方法签名与基类中的虚拟方法签名匹配。

【讨论】:

  • 我将为我的代码库使用特定的覆盖宏,但对于 sn-p 代码,我使用了 w/o 它。感谢那个参考错误,已修复,但代码仍然无法编译(更新失败编译信息)。阅读链接:)
  • 好吧,一切正常,它需要纯虚函数,除了参考错误。
猜你喜欢
  • 1970-01-01
  • 2020-01-15
  • 1970-01-01
  • 2010-10-13
  • 1970-01-01
  • 1970-01-01
  • 2015-03-16
  • 2012-09-08
  • 2012-10-06
相关资源
最近更新 更多