0

The following is a great simplification of my code:

data.h

#include "id.h"

namespace n1
{
    struct data
    {
        /* Relies on struct id */
    };
}

id.h

namespace n1
{

    struct data; // Forward declaration

    template <int dims>
    struct id
    {
        id(unsigned n);
        data operator*(unsigned n) const;
    };

    template <int dims>
    data operator*(unsigned n, id<dims> i);

} // namespace n1

id.cpp

#include "id.h"
#include "data.h"

using namespace n1;

// Force instantiation of struct id for template values 1, 2, and 3
template struct id<1>;
template struct id<2>;
template struct id<3>;

template <int dims>
id<dims>::id(unsigned n) {}

template <int dims>
data id<dims>::operator*(unsigned n) const
{
    return data();
}

// warning C4667: no function template defined that matches forced instantiation
template data operator*<1>(unsigned n, id<1> i);

template <int dims>
data operator*(unsigned n, id<dims> i)
{
    return i * n;
}

I'm using Visual Studio 2013. The first problem I encounter with this approach is the warning C4667. An alternative is to declare friend data operator*(unsigned n, id i) inside struct id and not forcing instantiation of this operator, which gets rid of the warning, but nothing else.

The real problem occurs when I decide to actually use this operator, e.g. in main():

using namespace n1;
id<1> i(7);      // Works fine
data d1 = i * 5; // Works fine
data d2 = 4 * i; // error LNK2019: unresolved external symbol
                 // struct n1::data __cdecl n1::operator*<1>(unsigned int,struct n1::id<1>

I believe this question to have basically the same problem, however it does not have an answer. My hoping is that my example is much simpler to identify the problem.

I tried all the suggestions from there, trying all combinations that I could find that were able to compile, but none of them were able to link. I guess an alternative would be to split structs id and data into multiple structs and files, however that may prove messy at this point.

Edit: The question is definitely not a duplicate of this one. As you can see from my code, I'm asking about explicit specialization for known data types, which I have been successful in implementing in a separate source file for everything except non-member operators. I have to admit that forced instantiation is a new trick for me, which I do not know how to use in this particular example.

Community
  • 1
  • 1
ProGTX
  • 11
  • 3

0 Answers0