1

I have run into a weird unresolved external symbol error with this class. I have a C++ library based on Qt where LIBDATASHARED_EXPORT is an alias for __declspec(dllexport) or __declspec(dllimport).

class LIBDATASHARED_EXPORT SaveFile
{
    class Index
    {
    public:
        operator bool() const; //<--- defined in cpp
    };

public:
    template<typename T> load()
    {
        Index idx;

        if(idx) //<--- complains about unresolved symbol...
        {

        }
    }
};

When I use this in another project where I link with the library I get the unresolved external symbol about the SaveFile::Index::operator bool() const when instantiating the template method. When I put the definition of SaveFile::Index::operator bool() const in the header it works fine. The definition of SaveFile::Index::operator bool() const is indeed in the same .cpp file as the rest of the class' definitions so it should be defined at the point of instantiation.

What is the problem here and how do I fix it?

Resurrection
  • 3,916
  • 2
  • 34
  • 56
  • Can you please read the question before you mark it as duplicate? It is not an issue of the template method not being defined in the header. It is defined in the header. The class itself is not templated. The inner class is not templated. The symbols of the enclosing class resolves fine but the symbol from inner class does not even though it is defined in the same translation unit and the library. – Resurrection Dec 06 '16 at 20:53
  • I, for one, read the question, and your problem was apparent after I read the following statement: _When I put the definition in the header it works fine._ – Algirdas Preidžius Dec 06 '16 at 20:59
  • @AlgirdasPreidžius Are you serious? I obviously mean definition of `SaveFile::Index::operator bool() const`, NOT the template. That is defined in the header all along. – Resurrection Dec 06 '16 at 21:00
  • I can't reproduce your problem (at least once I make your `operator bool` public). Please provide a [mcve] that will demonstrate the error you're seeing. – Miles Budnek Dec 06 '16 at 21:04
  • @MilesBudnek Edited the OP to include minimal source code to reproduce this. – Resurrection Dec 06 '16 at 21:13
  • Interesting. Do you see the error when building the library or when attempting to link against it? I ask because I can compile [almost](http://coliru.stacked-crooked.com/a/d19142861396bf52) [exactly](http://coliru.stacked-crooked.com/a/2a8f735c4dae3f6c) [that](http://coliru.stacked-crooked.com/a/d71c0574afd34399) minus the Qt and library stuff without error. – Miles Budnek Dec 06 '16 at 21:21
  • @MilesBudnek Only when linking against it. But I do not instantiate the template in the library so it cannot happen when compiling it anyway. But when I tried to instantiate it in the library it works fine... – Resurrection Dec 06 '16 at 21:22
  • @MilesBudnek Alright it seems that I have to manually add the export macro to the inner class as well in order to get its symbols export. Just checked with DependencyWalker that it did not actually export the inner class at all. – Resurrection Dec 06 '16 at 21:31

1 Answers1

1

The problem is that one has to export the inner classes as well so the solution in this case is to add the LIBDATASHARED_EXPORT to the inner class because it is not exported by the outer class (that itself is exported). Found out using Dependency Walker.

Resurrection
  • 3,916
  • 2
  • 34
  • 56