1

I have this header file and source file that are a part of a static library:

vector2.h

#pragma once

namespace lib2d
{


template<typename T>
struct Vector2
{
    Vector2();
    Vector2(const T& X, const T& Y);
    T x;
    T y;
};


}

template <typename T>
lib2d::Vector2<T>& operator +=(lib2d::Vector2<T>& left, const lib2d::Vector2<T>& right);

template < typename T>
lib2d::Vector2<T>& operator -=(lib2d::Vector2<T>& left, const lib2d::Vector2<T>& right);

vector2.cpp

#include "vector2.h"

namespace lib2d
{


template struct Vector2<float>;
template struct Vector2<int>;

template<typename T>
Vector2<T>::Vector2():
    x{ 0 },
    y{ 0 }
{
}

template<typename T>
Vector2<T>::Vector2(const T& X, const T& Y):
    x{ X }, 
    y{ Y }
{
}


}

template lib2d::Vector2<float>& operator +=(lib2d::Vector2<float>&, const lib2d::Vector2<float>&);
template lib2d::Vector2<int>& operator +=(lib2d::Vector2<int>&, const lib2d::Vector2<int>&);

template<typename T>
lib2d::Vector2<T>& operator +=(lib2d::Vector2<T>& left, const lib2d::Vector2<T>& right)
{
    left.x += right.x;
    left.y += right.y;
    return left;
}

template lib2d::Vector2<float>& operator -=(lib2d::Vector2<float>&, const lib2d::Vector2<float>&);
template lib2d::Vector2<int>& operator -=(lib2d::Vector2<int>&, const lib2d::Vector2<int>&);

template<typename T>
lib2d::Vector2<T>& operator -=(lib2d::Vector2<T>& left, const lib2d::Vector2<T>& right)
{
    left.x -= right.x;
    left.y -= right.y;
    return left;
}

When I build the library, everything builds successfully, but the vector2.cpp file gives me compiler warnings.

The warnings are:

Warning C4667 'lib2d::Vector2<float> &operator +=(lib2d::Vector2<float> &,const lib2d::Vector2<float> &)': no function template defined that matches forced instantiation

Warning C4667 'lib2d::Vector2<int> &operator +=(lib2d::Vector2<int> &,const lib2d::Vector2<int> &)': no function template defined that matches forced instantiation

Warning C4667 'lib2d::Vector2<float> &operator -=(lib2d::Vector2<float> &,const lib2d::Vector2<float> &)': no function template defined that matches forced instantiation

Warning C4667 'lib2d::Vector2<int> &operator -=(lib2d::Vector2<int> &,const lib2d::Vector2<int> &)': no function template defined that matches forced instantiation

I have several other operator overloads in this file (that I didn't include here to shorten the post) that are giving me the same warnings.

I have used the finished library in another project and everything seems to be working correctly. I am tempted to just ignore the warnings and move on but I've been told that you should always listen to compiler warnings so I feel reluctant to do so.

What is causing these warnings? Clearly I've both declared and implemented the function templates so what does it mean when it says that there is no such function template defined?

I've tried googling for an answer but I can't find a single post talking about this particular warning.

JensB
  • 839
  • 4
  • 19
  • First of all you should include all code in the header file. You can't just link templates - the definition is required when a template is instantiated. – Bernd Aug 10 '21 at 15:08
  • @Bernd I know that you have to implement templates in headers, but for some reason it doesn't seem to be needed when building a static library. I don't know enough about templates to explain how or why that's the case, but it is. The code in my post is what `vector2.h` and `vector2.cpp` look like in my project, and as I said I've exported the library and used it as intended in another project. I can successfully create instances of `vector2` and `vector2`. – JensB Aug 10 '21 at 15:23
  • 1
    Could you try to move the template instantiations after the definition? – Bernd Aug 10 '21 at 15:25
  • @Bernd Yeah, that fixed it. VS is still underlining the instantiations with green but neither code analysis nor build output is giving any warnings. Thanks for the help – JensB Aug 10 '21 at 16:22
  • @Bernd If you put that in an answer I can accept it. – JensB Aug 10 '21 at 16:25
  • [Why can templates only be implemented in the header file?](https://stackoverflow.com/questions/495021/) – Remy Lebeau Aug 10 '21 at 17:40

1 Answers1

2

As mentioned in my comment: an explicit template instantiation must appear after the template definition.

See https://en.cppreference.com/w/cpp/language/function_template:

An explicit instantiation definition forces instantiation of the function or member function they refer to. It may appear in the program anywhere after the template definition, and for a given argument-list, is only allowed to appear once in the program, no diagnostic required.

Bernd
  • 2,113
  • 8
  • 22