Ethan McTague
Ethan McTague

Reputation: 2358

Are there any means to allow for more complex type inference in C++ templates?

Suppose I have a template function:

template<class T>
void whenMatchesType(std::function<void(T*)> action) { ... }

I might invoke this like so:

anObject.whenMatchesType<SomeType>([=](SomeType *value) {
    // ...
});

Although C++ is capable of inferring template parameters from arguments of simple, non-template types, I don't seem to be able to omit explicitly specifying the type (as <SomeType>) in this case - even though it is provided as a type parameter to the first argument.

Is there some change to my code - or to my compilation - through which I might avoid this redundancy?

Upvotes: 0

Views: 92

Answers (1)

super
super

Reputation: 12928

If you need acces to the parameter type you can still take in the callable as it's own template parameter, then use type traits to extract the information.

Here is a simple example.

#include <iostream>
#include <functional>

template <typename T>
struct parameter_type;

template <typename ReturnType, typename ParameterType>
struct parameter_type<std::function<ReturnType(ParameterType)>> {
    using ParameterT = ParameterType;
};

template <typename T>
using param_t = typename parameter_type<decltype(std::function{std::declval<T>()})>::ParameterT;

template<class T>
void whenMatchesType(T) {
    using Parameter = param_t<T>;
    static_assert(std::is_same_v<Parameter, int>, "Only callables that take int as parameter is allowed");
}

int main() {
    whenMatchesType([](int){});
    //whenMatchesType([](double){});
}

Upvotes: 2

Related Questions