1

So I'm getting the following compile error :

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> >&)'

The implementation is as follows :

Writer.h

#ifndef WRITER_H
#define WRITER_H

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

Reader.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; 
}

I understand that by keeping the implementation in the header i should not occur error with undefined reference. Corrected the implementation in the write method to fit the interface. Still tho have compile errors. Reading the link.

user2207495
  • 325
  • 2
  • 12
  • 1
    Possible duplicate of [Why can templates only be implemented in the header file?](https://stackoverflow.com/questions/495021/why-can-templates-only-be-implemented-in-the-header-file) – Richard Critten Dec 23 '17 at 18:21
  • Agreed make sure you did not try to implement your templates in source files. – drescherjm Dec 23 '17 at 18:21

1 Answers1

3

Note that your implementation supplies void write(std::istringstream) methods taking a copy while undefined reference is for method taking a reference like void write(std::istringstream &) that you did not implement at base class virtual void write(T &in);. So you should update implementation with correct signature:

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

...

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

override specifier ensures that method signature matches to the virtual method signature in base class.

user7860670
  • 35,849
  • 4
  • 58
  • 84
  • I will use a specific override macro for my code base, but for snippet code I've used w/o it. Thx for that reference mistake, fixed but code still does not compile (updated fail compile information). Reading the links :) – user2207495 Dec 23 '17 at 18:35
  • Ok everything works, it required pure virtual function aside from that typo with reference. – user2207495 Dec 23 '17 at 18:42