0

I have some code that seems to me like it ought to work but throws an error when compiling.

The header file (min.hpp):

#include <type_traits>

namespace test {

    template <typename T1>
    T1 min(T1 a);
    template <typename T1, typename ... Args>
    typename std::common_type<T1, Args...>::type min(T1 a, Args ... args);

}

The implementation (min.cpp):

#include <type_traits>

namespace test {

    template <typename T1>
    T1 min(T1 a)
    {
        return a;
    }
    template <typename T1, typename ... Args>
    typename std::common_type<T1, Args...>::type min(T1 a, Args ... args)
    {
        typename std::common_type<Args...>::type b = min(args...);
        return a > b ? b : a;
    }

}

Calling the function (demo.cpp):

#include <cstdio>
#include "min.hpp"

int main()
{
    int x = test::min(1, 2, 3);
    std::printf("%d\n", x);

    return 0;
}

Compiling: g++ min.cpp demo.cpp -std=gnu++17 -o main

Error message:

Undefined symbols for architecture x86_64:
  "std::__1::common_type<int, int, int>::type test::min<int, int, int>(int, int, int)", referenced from:
      _main in demo-5e729b.o
ld: symbol(s) not found for architecture x86_64

However, the code works fine if I move the main() function from the separate file to min.cpp. Why do I get this error and how can I fix it?

mwpuppire
  • 13
  • 4
  • 2
    your template definitions need to be in the header – Alan Birtles Jan 28 '21 at 21:00
  • 2
    Not the answer, but A: we already have `std::min({1,2,3})`, and B: consider using a fold expression instead of recursion. – HolyBlackCat Jan 28 '21 at 21:00
  • Thanks @AlanBirtles. I didn't realize that. – mwpuppire Jan 28 '21 at 21:02
  • 1
    Related: https://en.cppreference.com/w/cpp/language/fold – Bob__ Jan 28 '21 at 21:04
  • @mwpuppire Also, the error is not a compiler error. It is a linker error (`ld` is the linker). You will see that the object file `demo-5e729b.o` was successfully created, meaning the compilation went through without any issues. It is the linker that is complaining that the function you're calling can't be found. – PaulMcKenzie Jan 28 '21 at 21:20

0 Answers0