0

By analyzing some code using SonarLint, I saw it complaining about the second parameter (Args... args) of the function below. It says:

"std::forward" should only be called on a forwarding reference.

link to the documentation

Here is my code:

#include <iostream>
#include <chrono>
#include <utility>
#include <functional>


template < typename Time = std::chrono::microseconds,
           typename Clock = std::chrono::steady_clock >
struct FunctionTimer
{
    template < typename F, typename... Args >
    static Time duration( F&& f, Args... args )
    {
        auto start { Clock::now( ) };
                                        // here it says that I shouldn't use std::forward because
                                        // `args` is not a forwarding reference
        std::invoke( std::forward<F>( f ), std::forward<Args>( args )... );

        auto end { Clock::now( ) };

        return std::chrono::duration_cast<Time>( end - start );
    }
};


void test_func( const int param )
{
    std::cout << param << " Testing...\n";
}

int main( )
{
    const auto time { FunctionTimer<>::duration( test_func, 5 ) };
    std::cout << std::chrono::duration<double, std::milli>( time ).count( ) << '\n';
}

So is this a misleading warning? If not then how should I fix it and make it right?

digito_evo
  • 3,216
  • 2
  • 14
  • 42
  • 1
    Looks legit, args isn't any sort of reference. https://en.cppreference.com/w/cpp/utility/functional/invoke has the right syntax example in the "possible implementations" – Mat Jun 11 '22 at 18:11
  • 6
    `Args... args` => `Args&&... args` – n. m. could be an AI Jun 11 '22 at 18:19
  • @n. 1.8e9-where's-my-share m. Yes, seems like I forgot that thing. But could you tell me about the differences between adding that `&&` and not adding it? I mean the code seems to work well without it, so what will change if I add that `&&` to the code? Any kind of performance difference or is it just for compiler magic? – digito_evo Jun 11 '22 at 18:29
  • 1
    @digito_evo - The && is if you want to forward rvalues (as rvalues) to std::invoke. As it is now, std::forward has no effect (thus the warning). – BoP Jun 11 '22 at 18:59
  • @digito_evo read up about [Forwarding references](https://en.cppreference.com/w/cpp/language/reference#Forwarding_references) and [`std::forward()`](https://en.cppreference.com/w/cpp/utility/forward) on cppreference.com – Remy Lebeau Jun 12 '22 at 02:09

0 Answers0