Home > database >  Why use decltype on a template argument?
Why use decltype on a template argument?

Time:06-24

In https://github.com/stlab/libraries/blob/main/stlab/concurrency/main_executor.hpp, I read

struct main_executor_type {
    using result_type = void;

    template <typename F>
    void operator()(F f) const {
        using f_t = decltype(f);

        dispatch_async_f(dispatch_get_main_queue(), new f_t(std::move(f)), [](void* f_) {
            auto f = static_cast<f_t*>(f_);
            (*f)();
            delete f;
        });
    }
};

What is the point of the decltype(f), why no simply use F?

CodePudding user response:

It depends, since there're some cases leading to different effect between F and decltype(f).

For example, F could be specified explicitly as array or function type, and the type of function parameter will be adjusted to pointer. Then F and decltype(f) give different result.

template <typename F> // suppose F is specified as array of T or function type F
void operator()(F f) const {
    using f_t = decltype(f); // f_t will be pointer to T or pointer to F
    ...
}

CodePudding user response:

I cannot see any useful scenario for this particular code example (please correct me if I'm wrong), but it would look differently if the parameter would have been declared as cv-qualified, e.g. const F f. Then, using f_t = decltype(f); would evaluate to const F, while using f_t = F; would remove cv qualifiers and evaluate to F.

Consider the following minimalistic example for better understanding:

#include <type_traits>

template <typename T>
void foo(const T t) {
    using X = decltype(t);
    static_assert(std::is_const_v<X>); // will fail if using X = T;
}

int main() {
    const int a = 123;
    foo(a); // T will be deduced to int, i.e. cv qualifiers are removed
}
  • Related