Question

I am encountering a problem very similar to the topic addressed here: How to properly specialize a templatized static const member that is the same type as its parent

Here's my code:

template <class T>
class p3d
{
public:
    p3d() {
        x = 0;
    }

    p3d(const T &_x) {
        x = _x;
    }

    static const p3d<T> origin;

    T x;
};

typedef p3d<float> p3df;

int main(int, char**)
{
    p3df p = p3df::origin;
    return 0;
}

// elsewhere in a *.cpp file
template<> const p3df p3df::origin(0.0f);

When compiled under a strict compiler like Clang, I get the following error:

explicit specialization of 'origin' after instantiation
template<> const p3df p3df::origin(0.0f); -> implicit instantiation first required here

The solution is to move

template<> const p3df p3df::origin(0.0f);

to be before the typedef. The problem with this solution is that it results in multiply-defined symbols, because now p3df::origin is defined in every file that uses the vector header. Is there any way to properly specialize the static const typedef-ed templates, while avoiding duplicate definitions in all source files using the typedef?

Was it helpful?

Solution

Just move the line

template<> const p3df p3df::origin(0.0f);

before the main() function, but after the typedef.

I am really not sure what the problem is here. It seems like clang complains that you're providing a definition for the template specialization after using said specialization. gcc/4.9 (nightly build) does not have an issue with it.

Generally speaking, having a static template definition in a header file is cool, since they are - as the name implies - templates. However, if you specialize your template, thereby making it an actual class, the one definition rule applies as to any regular class, and you need to move the definition to a non-header file.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top