Search code examples
c++templatesc++14sfinae

Using a templated function parameter type name to call a function


I am using a C API that defines some functions for different types. Something like:

// defined in a header:
extern "C" A* A_create();
extern "C" B* B_create();

Is it possible to call these functions from a templated C++ function such that the template type parameter determines the C function to call?

Something like:

// Template specialization for when T_create() exists
template <typename T>
auto create() -> declval( T##_create() ) {

    // This is not valid syntax, but I'd like to call A_create() if this
    // template is instantiated with A, B_create() if this is
    // instantiated with B, etc. If the function doesn't exist, I'd like
    // the compiler to fall back to the generic implementation below.
    return T##_create() 
}

// Template specialization for when T_create() doesn't exist
template <typename T>
T* create() { 
    return new T; // generic version just calls new. 
}

Just wondering if its possible to do this without making explicit specializations of the create() function for each type coming from the C api.


Solution

  • Since there's no parameter to use, I would probably just use a function with specializations:

    // generic version just calls new. 
    template<class T>
    T* create() { return new T;}
    template<>
    A* create() {return A_create();}
    template<>
    B* create() {return B_create();}
    

    Then usage should be trivial:

    A* ptr = create<A>();
    

    You can't avoid the specializations, but you can make them easy.
    #define make_lib_create(T) template<> \
    T* create() {return T##_create();}
    make_lib_create(A);
    make_lib_create(B);