0

I have written some template based codes to extract functions argument list in order to perform some strict type extraction and type checking. Here is part of code:

#include <type_traits>
#include <tuple>
#include <iostream>

template<typename>
struct function_traits {};

template <typename Return, typename... Args>
struct function_traits<Return (*)(Args...)>
{
    template<std::size_t N>
    using type = typename std::tuple_element<N, std::tuple<Args...>>::type;

    static constexpr size_t callback_param_cnt = sizeof...(Args);
};

template<typename T, std::size_t N = function_traits<T>::callback_param_cnt>
struct callback_info {};

template<typename T>
struct callback_info<T, 1> {
    constexpr static size_t val = function_traits<T>::callback_param_cnt;
};

template<typename T>
struct callback_info<T, 2> {
    constexpr static size_t val = function_traits<T>::callback_param_cnt;
};

void foo(int) {
}

int main() {
    function_traits<decltype(&foo)>::type<0> x;
    std::cout << callback_info<decltype(&foo)>::val;
}

The code compiles without any problem. function_traits extract function information including number and type of arguments. callback_info just using function_traits to extract some info for 1 and 2 argument functions. As you see, this code compiles without any problem and val in callback_info gets correct number of arguments(This is a test code to make sure that I can use function_traits inside callback_info). But here is my problem: event though my function_traits::type works in the main, I want to use it in callback_info to save argument types. Something like this:

template<typename T, std::size_t N = function_traits<T>::callback_param_cnt>
struct callback_info {};

template<typename T>
struct callback_info<T, 1> {
    using Type1 = typename function_traits<T>::type<0>;
    constexpr static size_t val = function_traits<T>::callback_param_cnt;
};

template<typename T>
struct callback_info<T, 2> {
    using Type1 = typename function_traits<T>::type<0>;
    using Type2 = typename function_traits<T>::type<1>;
    constexpr static size_t val = function_traits<T>::callback_param_cnt;
};

But this code does not compile. It seems because template deduction fails, it cannot find type here. Why this happens? How I can solve this problem? In addition, how I can change function_traits to detect reference arguments too? because it currently detect int& argument as int right now.

Afshin
  • 8,839
  • 1
  • 18
  • 53
  • 3
    Try adding `template` keyword as `typename function_traits::template type<0>;`. – songyuanyao Apr 11 '20 at 12:35
  • @songyuanyao that just did the trick. why it does not work right now? – Afshin Apr 11 '20 at 12:36
  • See [where-and-why-do-i-have-to-put-the-template-and-typename-keywords](https://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords) – Jarod42 Apr 11 '20 at 12:37
  • Your traits handle reference argument: [Demo](https://coliru.stacked-crooked.com/a/fe36561befa0f378). – Jarod42 Apr 11 '20 at 12:43
  • @Afshin You just have to specify `template` explicitly to tell the compiler that `type` is a template; it's a dependent name. See the link Jarod42 posted for more. – songyuanyao Apr 11 '20 at 12:44
  • I was checking type with `__cxa_demangle()`. it seems that it does not show reference argument correctly. Thanks a lot for help. – Afshin Apr 11 '20 at 12:51

0 Answers0