强制所有&&执行?

Vin*_*ent 8 c++ logic templates variadic-templates c++11

考虑以下可变参数函数

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
} 
Run Code Online (Sandbox Code Playgroud)

如果有一个递归级别false,那么我怀疑以下内容不会被执行.是否有一个技巧来强制所有参数的递归,即使其中一个返回false

And*_*owl 21

这不应该太难:

template <typename Type, typename... Types>
bool f(Type& arg, Types&... args)
{
    bool b1 = f(arg);
    bool b2 = f(args...);
    return b1 && b2;
}
Run Code Online (Sandbox Code Playgroud)


Vin*_*ent 11

由于辩论是在AndyProwl和Alon解决方案的比较中演变而来的,我已经对两种解决方案进行了基准测试,结果......取决于参数的数量.

编译:

g++-4.7 -std=c++11 -Wall -Wextra -O3 main.cpp -o main -D_FIRST
Run Code Online (Sandbox Code Playgroud)

对AndyProwl解决方案进行基准测试并编译:

g++-4.7 -std=c++11 -Wall -Wextra -O3 main.cpp -o main -D_SECOND
Run Code Online (Sandbox Code Playgroud)

基准测试Alon解决方案.

这是10个参数的基准程序.

#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;
}
Run Code Online (Sandbox Code Playgroud)

对于具有给定数量的参数的每个解决方案,有50个基准,分散非常小,并且这些基准的平均时间是可靠的指标.

我的第一个基准测试是使用"正确"数量的参数,其中Alon解决方案比AndyProwl解决方案更快.

最终结果如下:

基准

所以AndyProwl解决方案通常比Alon解决方案更快.所以,现在我可以验证你的答案.但我认为差异是如此之小,以至于它依赖于架构/编译器.

所以:

  • AndyProwl + 1为您提供通常更快的解决方案
  • Alon + 1为您的constexpr就绪解决方案

  • 好图,谢谢你分享信息.+1 (2认同)