Templates require specific handling because the bindings parser attempts to instantiate every template it encounters.
Use requires for constrained members
If a member function is only valid for certain template arguments, you must annotate it with requires. To maintain compatibility across platforms that may not support C++20, use the MR_REQUIRES_IF_SUPPORTED macro from MRMesh/MRMacros.h.
template <typename T>
struct Pair
{
T first, second;
T sum() const MR_REQUIRES_IF_SUPPORTED( std::is_arithmetic_v<T> )
{
return first + second;
}
};
Manually instantiate templates
Non-member template functions and class templates must be manually instantiated for the desired types using the MR_BIND_TEMPLATE macro, unless an extern template already exists.
template <typename T> T foo(T t) {...}
MR_BIND_TEMPLATE( int foo(int t) )
MR_BIND_TEMPLATE( float foo(float t) )
Prefer friend definitions
Instead of free functions, use friend definitions inside classes (e.g., for overloaded operators or begin()/end()). The parser automatically instantiates friend functions, whereas free functions require manual MR_BIND_TEMPLATE calls.
template <typename T>
struct Pair
{
T first, second;
T sum() const MR_REQUIRES_IF_SUPPORTED( std::is_arithmetic_v<T> )
{
return first + second;
}
};
// Manual instantiation for free functions
template <typename T> T foo(T t) {...}
MR_BIND_TEMPLATE( int foo(int t) )
MR_BIND_TEMPLATE( float foo(float t) )
// Preferred approach for operators
template <typename T>
struct A
{
friend A operator+(A, A) {...}
};