Using CRTP as an alternative to abstract static methods in C++11
<p>I'm trying to implement a generic resource manager which would ensure that every resource gets only loaded once with C++11.</p>

<p>My first attempt:</p>

<p><strong>resourcemanager.h</strong></p>

<pre><code>#ifndef RESOURCEMANAGER_H
#define RESOURCEMANAGER_H

#include &lt;map&gt;
#include &lt;memory&gt;


template&lt;typename T&gt;
class ResourceManager {

public:
    static std::shared_ptr&lt;T&gt; load(std::string filePath);

private:
    static map&lt;std::string, std::weak_ptr&lt;T&gt;&gt; resources;
    virtual static std::shared_ptr&lt;T&gt; loadResource(std::string filePath) = 0;
};

#endif // RESOURCEMANAGER_H

#include "resourcemanager.h"
</code></pre>

<p><strong>resourcemanager.cpp</strong></p>

<pre><code>using namespace std;

template&lt;typename T&gt;
map&lt;string, weak_ptr&lt;T&gt;&gt;  ResourceManager&lt;T&gt;::resources;

template&lt;typename T&gt;
shared_ptr&lt;T&gt; ResourceManager&lt;T&gt;::load(std::string filePath) {
    auto search = resources.find(filePath);
    if (search != resources.end()) {
        auto ptr = search-&gt;second.lock();
        if (ptr) {
            return ptr;
        }
    }
    auto ptr = loadResource(filePath);
    resources[filePath] = ptr;
    return ptr;
}
</code></pre>

<p>However since abstract static methods are apparently forbidden black magic I tried to use CRTP:</p>

<p><strong>resourcemanager.h</strong></p>

<pre><code>#ifndef RESOURCEMANAGER_H
#define RESOURCEMANAGER_H

#include &lt;map&gt;
#include &lt;memory&gt;

template&lt;typename T, class Derived&gt;
class ResourceManager {

public:
    static std::shared_ptr&lt;T&gt; load(std::string filePath);

private:
    static std::map&lt;std::string, std::weak_ptr&lt;T&gt;&gt; resources;
    static std::shared_ptr&lt;T&gt; loadResource(std::string filePath);
};

#endif // RESOURCEMANAGER_H
</code></pre>

<p><strong>resourcemanager.cpp</strong></p>

<pre><code>#include "resourcemanager.h"

using namespace std;

template&lt;typename T, class Derived&gt;
map&lt;string, weak_ptr&lt;T&gt;&gt;  ResourceManager&lt;T, Derived&gt;::resources;

template&lt;typename T, class Derived&gt;
shared_ptr&lt;T&gt; ResourceManager&lt;T, Derived&gt;::load(string filePath) {
    auto search = resources.find(filePath);
    if (search != resources.end()) {
        auto ptr = search-&gt;second.lock();
        if (ptr) {
            return ptr;
        }
    }
    auto ptr = ResourceManager::loadResource(filePath);
    resources[filePath] = ptr;
    return ptr;
}

template&lt;typename T, class Derived&gt;
shared_ptr&lt;T&gt; ResourceManager&lt;T, Derived&gt;::loadResource(string filePath) {
    return Derived::loadResource(filePath);
}
</code></pre>

<p>This looks like it should do what I want. However when I try to use it, it fails at the linking stage:</p>

<p><strong>managedstring.h</strong></p>

<pre><code>#ifndef MANAGEDSTRING_H
#define MANAGEDSTRING_H

#include "resourcemanager.h"

class ManagedString {

public:
    ManagedString(std::string filePath);
    std::string get();

private:
    std::shared_ptr&lt;std::string&gt; ptr;

    class StringManager : public ResourceManager&lt;std::string, StringManager&gt; {
    private:
        static std::shared_ptr&lt;std::string&gt; loadResource(std::string filePath);
    };
};

#endif // MANAGEDSTRING_H
</code></pre>

<p><strong>managedstring.cpp</strong></p>

<pre><code>#include "managedstring.h"

using namespace std;

ManagedString::ManagedString(string filePath) {
    ptr = StringManager::load(filePath);
}

string ManagedString::get() {
    return *ptr;
}

shared_ptr&lt;string&gt; ManagedString::StringManager::loadResource(string filePath) {
    // dummy implementation
    return make_shared&lt;string&gt;("foo");
}
</code></pre>

<p><strong>main.cpp</strong></p>

<pre><code>#include &lt;iostream&gt;
#include "managedstring.h"

using namespace std;

int main() {
    ManagedString string1 = ManagedString("bar");
    ManagedString string2 = ManagedString("foobar");
    cout &lt;&lt; string1.get() &lt;&lt; endl; 
    cout &lt;&lt; string2.get() &lt;&lt; endl; 
}
</code></pre>

<p>When I try to compile this with <code>g++ -std=c++11 -o bin -Wall main.cpp managedstring.cpp resourcemanager.cpp</code> (using gcc version 5.3.0) I get this error message:</p>

<pre><code>/tmp/ccgqljOQ.o: In function `ManagedString::ManagedString(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;)':
managedstring.cpp:(.text+0xdd): undefined reference to `ResourceManager&lt;std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;,
 ManagedString::StringManager&gt;::load(std::__cxx11::basic_string&lt;char, std::char_traits&lt;char&gt;, std::allocator&lt;char&gt; &gt;)'
</code></pre>

<p>Should this work? Is this a compiler shortcoming? Or am I trying to do something I shouldn't do.</p>

<p>I also thought about altering my design, however I think it's not that bad. Feel free to disagree with me on this.</p>