1

Is there a possibility to check at compile-time if a function of a class-template or a free template-function is instantiated throughout the code of a specific TU?

template<typename T>
struct A {
    inline static void f() {}
};
template<typename U>
void g() {}

int main() {
     A<int>::f();
}

static_assert(some_check_v<A>); // for A<int>::f() -> ok
static assert(some_check_v<...>); // g<int>() -> nok

Something like the above?

The purpose should be to prevent the user from missing a specific call to a function.

wimalopaan
  • 4,838
  • 1
  • 21
  • 39

1 Answers1

1

Although this is somewhat deprecated by the introduction of concepts in newer versions of C++, if you're stuck on an older version, this should do the job for free template funtions:

template<typename Type_T>
constexpr int MyFunction() = delete; //The function

template<>
constexpr int MyFunction<bool>() //A specialisation for bool
{
    return 1;
}
//The type traits
namespace Internal 
{ 
    template<typename Type_T, typename = void> 
    struct IsMyFunctionImplemented : std::false_type 
    { }; 
    
    template<typename Type_T> 
    struct IsMyFunctionImplemented<Type_T
        , std::void_t<decltype(MyFunction<Type_T>())>
        > : std::true_type 
    { }; 
} 
template<typename Type_T> 
inline constexpr bool IsMyFunctionImplemented_v = Internal::IsMyFunctionImplemented<Type_T>::value;

Usage:

IsMyFunctionImplemented_v<bool>; //returns true
IsMyFunctionImplemented_v<float>; //returns false

Working example here: https://godbolt.org/z/qGn5WGGrc

Note that the default implementation for the function template has to be declared as deleted, otherwise this will not work!

This is because any call towards MyFunction<Type_T>() is allowed if there is a default implementation, and thus the expression std::void_t<decltype(MyFunction<Type_T>())> does not equate to void because decltype(MyFunction<Type_T>()) provides a valid function signature.

Also note that this only validates the function name and arguments, not its return type, if this is important to you, you'll need to make some modifications, here's a great example for member functions:
Check if a class has a member function of a given signature