Metal Shader C++ Templates

So in C++ the following compiles:


// foo.hpp

template <typename T> T foo(T bar);


// foo.cpp

#include "foo.hpp"

template <typename T> T foo(T bar)
{
  bar++;
  return bar;
}

template char foo(char bar);


// main.cpp

#include "foo.hpp"

extern template char foo(char bar);

char Cplusplus()
{
  return foo('C');
}


int main() {}


If I copy all code except main() into a Metal shader library with foo.hpp, foo.metal and main.metal and try to compile, then at the linking step I get the following:


metallib: multiple symbols ('_Z3fooIcET_S0_') with incompatible linkages!


Is there any way to use templates in Metal that doesn't involve any code duplication? (i.e. defining templates in headers, trivial specializations, etc)

Replies

Have you tried the function inline like the following?

template <typename T>
inline T foo(T bar){...}

Hope it helps.

I have a very large template library to work with, I'm just wondering if I can avoid having to inline all of it. Thanks.

I read somewhere that Metal compiler converts to inline functions anyway for optimization. I think if you can get away with program scope functions, but not really for accessing everywhere. Maybe those Apple staff guys can give you much more affirmative answers; I only speak on my experiences.

Keep all your templates in headers. I'm guessing "extern template" isn't supported in Metal.


You could use explicit specializations if compile time is an issue.