Consider the following variadic function
template <typename Type, typename... Types>
bool f(Type& arg, Types&... args)
{
return f(arg) && f(args...);
}
template <typename Type>
bool f(Type& arg)
{
// Do something
}
If one level of recursion is false
, then I suspect that the following will not be executed. Is there a trick to force the recursion on all arguments even if one of them returns false
?
In Physics, force is defined as: The push or pull on an object with mass causes it to change its velocity. Force is an external agent capable of changing a body's state of rest or motion. It has a magnitude and a direction.
Nine more characters for Jump ForceSeto Kaiba from Yu-Gi-Oh! All Might from My Hero Academia. Hunter x Hunter Biscuit Krueger. Toushirou Hitsugaya from Bleach.
Bandai Namco is pulling Jump Force, the anime crossover fighting game that features characters from Dragon Ball, Naruto, One Piece, JoJo's Bizarre Adventure, and other series, from digital stores on Feb. 7, 2022.
This shouldn't be too hard:
template <typename Type, typename... Types>
bool f(Type& arg, Types&... args)
{
bool b1 = f(arg);
bool b2 = f(args...);
return b1 && b2;
}
As the debate has evolved in a comparison of the AndyProwl and Alon solution, I've benchmarked the both solution, and the result ... depends of the number of arguments.
Compiling with:
g++-4.7 -std=c++11 -Wall -Wextra -O3 main.cpp -o main -D_FIRST
benchmarks the AndyProwl solution and compiling with :
g++-4.7 -std=c++11 -Wall -Wextra -O3 main.cpp -o main -D_SECOND
benchmarks the Alon solution.
Here is the program of the benchmark for 10 arguments.
#include <iostream>
#include <chrono>
// Function 1 : with &&
template <typename Type>
inline bool f1(const Type& arg)
{
return arg;
}
template <typename Type, typename... Types>
inline bool f1(const Type& arg, const Types&... args)
{
bool arg1 = f1(arg);
bool arg2 = f1(args...);
return arg1 && arg2;
}
// Function 2 : with &
template <typename Type>
inline bool f2(const Type& arg)
{
return arg;
}
template <typename Type, typename... Types>
inline bool f2(const Type& arg, const Types&... args)
{
return f2(arg) & f2(args...);
}
// Benchmark
int main(int argc, char* argv[])
{
// Variables
static const unsigned long long int primes[10] = {11, 13, 17, 19, 23, 29, 31, 37, 41, 43};
static const unsigned long long int nbenchs = 50;
static const unsigned long long int ntests = 10000000;
unsigned long long int sum = 0;
double result = 0;
double mean = 0;
std::chrono::high_resolution_clock::time_point t0 = std::chrono::high_resolution_clock::now();
// Loop of benchmarks
for (unsigned long long int ibench = 0; ibench < nbenchs; ++ibench) {
// Initialization
t0 = std::chrono::high_resolution_clock::now();
sum = 0;
// Loop of tests
for (unsigned long long int itest = 1; itest <= ntests; ++itest) {
#ifdef _FIRST
sum += f1((itest+sum)%primes[0], (itest+sum)%primes[1], (itest+sum)%primes[2], (itest+sum)%primes[3], (itest+sum)%primes[4], (itest+sum)%primes[5], (itest+sum)%primes[6], (itest+sum)%primes[7], (itest+sum)%primes[8], (itest+sum)%primes[9]);
#endif
#ifdef _SECOND
sum += f2((itest+sum)%primes[0], (itest+sum)%primes[1], (itest+sum)%primes[2], (itest+sum)%primes[3], (itest+sum)%primes[4], (itest+sum)%primes[5], (itest+sum)%primes[6], (itest+sum)%primes[7], (itest+sum)%primes[8], (itest+sum)%primes[9]);
#endif
}
// Finalization
result = std::chrono::duration_cast<std::chrono::duration<double>>(std::chrono::high_resolution_clock::now()-t0).count();
mean += result;
std::cout<<"time = "<<result<<" (sum = "<<sum<<")"<<std::endl;
}
// End
std::cout<<"mean time = "<<mean/nbenchs<<std::endl;
return 0;
}
With 50 benchmarks for each solution with a given number of arguments, the dispersion is very small, and the mean time over these benchmarks is a reliable indicator.
My first benchmark has been with the "right" number of arguments where the Alon solution is faster than the AndyProwl solution.
The final results are here :
So the AndyProwl solution is generally faster than the Alon one. So, now I can validate your answer. But I think that the difference is so small that it's architecture/compiler dependent.
So:
You can execute them separately and return a bool expression:
bool b0 = f(arg);
bool b1 = f(args);
return b0 && b1;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With