如何在C ++程序中报告函数评估的数量

时间:2017-01-12 13:29:37

标签: c++

我编写了一个C ++程序,它计算最小化函数的算法的目标函数值。我想知道算法使用了多少目标函数评估。还有许多其他函数将调用称为目标值函数。

我这里有一个演示代码......

#include <iostream>    
#include <stdlib.h>    


using namespace std;

void prnt(){
    static int num = 0;
    cout << "Hello" << endl;
    num++;
    cout << num << endl;
}

void callprnt(){
    prnt();
}

int main() {

    for (int i = 0; i < 8; ++i)
    {
        prnt();
    }

    for (int i = 0; i < 10; ++i)
    {
        callprnt();
    }

}

正如您所看到的,我可以在prnt()函数中显示正在进行多少目标函数评估,但我想在main中访问它。知道如何有效地跟踪主要功能评估的数量吗?

3 个答案:

答案 0 :(得分:3)

有几种方法可以解决这个问题。

糟糕的方法是使用全局变量。

更好的方法是返回计数,或传入变量(如指针或引用)以跟踪。

或者你可以在课堂上跟踪。

using namespace std;

class Printer
{
public:
    Printer() : num(0) {}
    void prnt() {
        cout << "Hello" << endl;
        num++;
        cout << num << endl;
    }
    int count()
    {
        return num;
    }
private:
    int num;
};

void callprnt(Printer & p) {
    p.prnt();
}

int main() {
    Printer p;
    for (int i = 0; i < 8; ++i)
    {
        p.prnt();
    }

    for (int i = 0; i < 10; ++i)
    {
        callprnt(p);
    }

    cout << "Total count: " << p.count() << '\n';
}

一般情况下,你可以让Printer实际上成为一个计数器,并传递你需要调用的函数。

答案 1 :(得分:1)

如果你可以使用C ++ 17,你可以这样做:

#include <iostream>

template<auto> struct counter { static int value; };
template<auto F> int counter<F>::value = 0;

void prnt() { ++counter<&prnt>::value; }
void callprnt() { ++counter<&callprnt>::value; prnt(); }

int main() {
    for (int i = 0; i < 8; ++i) { prnt(); }
    for (int i = 0; i < 10; ++i) { callprnt(); }
    std::cout << counter<&prnt>::value << std::endl;
    std::cout << counter<&callprnt>::value << std::endl;
}

在C ++ 14中,您可以使用以下定义:

template<void(*)()> struct counter { static int value; };
template<void(*F)()> int counter<F>::value = 0;

无论如何,它们被约束为函数类型void(void) 通过一些工作,您可以调整解决方案,使其接受任何类型的功能 作为一个最小的工作示例:

#include <iostream>

template<typename R, typename... A>
struct family {
    template<R(*)(A...)>
    struct wrapper {
        static int value;
    };
};

template<typename R, typename... A>
template<R(*F)(A...)>
int family<R, A...>::wrapper<F>::value = 0;

template<typename R, typename... A>
constexpr family<R, A...> fam(R(*)(A...));

void prnt() { ++decltype(fam(&prnt))::template wrapper<prnt>::value; }
void callprnt() { ++decltype(fam(&callprnt))::template wrapper<callprnt>::value; prnt(); }

int main() {
    for (int i = 0; i < 8; ++i) { prnt(); }
    for (int i = 0; i < 10; ++i) { callprnt(); }
    std::cout << decltype(fam(&prnt))::template wrapper<prnt>::value << std::endl;
    std::cout << decltype(fam(&callprnt))::template wrapper<callprnt>::value << std::endl;
}

答案 2 :(得分:0)

@nbro帮我解决了这个问题:

#include <iostream>    
#include <stdlib.h>    


using namespace std;

static int num = 0;


void prnt(){

    cout << "Hello" << endl;
    num++;
}

void callprnt(){
    prnt();
}

int main() {


    for (int i = 0; i < 8; ++i)
    {
        prnt();
    }

    for (int i = 0; i < 10; ++i)
    {
        callprnt();
    }

    cout << "The total number of iterations is " << num << endl;

}

我有点不确定这是否是最佳方式,或者是否可以做得更好。

看起来有更好的方法可以做到这一点..