samedi 2 novembre 2019

Forwarding wrapper using enable_if failing

I am trying to create a forwarding wrapper function which times the call of a function in C++14. There are 2 types I need to deal with, one is timing a function which doesn't return a value as follows. There might be operations which I need to do before and after the call which I am skipping here, so I cannot just do return func(), which deals with both void and non-void types.

Here is the wrapper for the void function.

template<typename T, typename ...U>
    auto time_function(T&& func, U&& ...args) -> typename enable_if<is_same<decltype(func(args...)), void>::value>::type
{
    std::cout<<"timing void function"<<std::endl;
    std::forward<T>(func)(std::forward<U>(args)...);

    std::cout<<"timing over"<<std::endl;
}

Wrapper for the non-void function

 template<typename T, typename ...U>
auto time_function(T&& func, U&& ...args) -> typename enable_if<!is_same<decltype(func(args...)), void), decltype(func(args...))>::value>::type
{
    std::cout<<"timing returning function"<<std::endl;
    auto val = std::forward<T>(func)(std::forward<U>(args)...);

    std::cout<<"timing over"<<std::endl;

    return val;
}


int main()
{

    time_function(foo, 2);
    int i = time_function(&foo_return, 1); //this generates an error
    //std::cout<<i<<std::endl;

}

foo is a function which returns void, and foo_return returns an integer. The error that is generated is

 auto time_function(T&& func, U&& ...args) -> typename enable_if<!is_same<decltype(func(args...)), void), decltype(func(args...))>::value>::type

<source>:28:99: error: template argument 2 is invalid

<source>:28:55: error: expected nested-name-specifier before 'enable_if'

 auto time_function(T&& func, U&& ...args) -> typename enable_if<!is_same<decltype(func(args...)), void), decltype(func(args...))>::value>::type

<source>:28:55: error: expected initializer before 'enable_if'

 auto time_function(T&& func, U&& ...args) -> typename enable_if<!is_same<decltype(func(args...)), void), decltype(func(args...))>::value>::type

<source>: In function 'int main()':

<source>:42:41: error: no matching function for call to 'time_function(int (*)(int), int)'

To my knowledge, the wrapper is correct, what is wrong? I am checking if the return-type of the function is void using is_same, and if so, declaring the return type I wish using enable_if.

Aucun commentaire:

Enregistrer un commentaire