techbech
techbech

Reputation: 3874

Pass on already deduced type as parameter type for a callback

So I'm trying to do something like the following

int x = 123;
myFunction(x, [](auto y) {
    std::cout << y;
});

And myFunction is defined as

template <typename T>
void myFunction(T val, void(*callback)(T)) {
    callback(val);
} 

When trying to compile the code clang gives me the error could not match 'void (*)(T)' against '(lambda at ...)'. I've figured out this is because you can't deduce the type from a lambda.

So that's actually alright because what I actually want is the parameter type of the callback to be the type deduced from the val parameter of myFunction.

So my question put simply is, is it possible somehow to exclude the callback parameter from being deduced and instead just use the deduced type of val?

Upvotes: 1

Views: 70

Answers (2)

max66
max66

Reputation: 66230

is it possible somehow to exclude the callback parameter from being deduced and instead just use the deduced type of val?

Sure.

If you define something like this

template <typename T>
struct self
 { using type = T; };

you can define myFunction() as follows

template <typename T>
void myFunction(T val, void(*callback)(typename self<T>::type)) {
    callback(val);
} 

Now T is deduced from val and used for callback.

Starting from C++20, you can avoid the self definition and use the newly introduced std::type_identity_t

template <typename T>
void myFunction(T val, void(*callback)(std::type_identity_t<T>)) {
    callback(val);
} 

Upvotes: 1

code_fodder
code_fodder

Reputation: 16391

One option (and there are a few) is to pass the callable item as a template argument and allow templating to take care of some of the details for you - eg:

template <typename T, typename FUNCTOR>
void myFunction(T val, FUNCTOR callback) {
    callback(val);
}

// Note: could be a const ref:
//void myFunction(T val, const FUNCTOR &callback) {


int main()
{

    int some_int{1};
    myFunction(some_int, [](auto y){ std::cout << y << std::endl; });

    float some_float{1.1f};
    myFunction(some_float, [](auto y){ std::cout << y << std::endl; });

    return 0;
}

Full example here (following your code - but this could be further tidied): https://godbolt.org/z/qr7T5GPd6

Upvotes: 1

Related Questions