2017-01-12 48 views
1

我已經編寫了一個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()顯示目標函數評估有多少發生的功能,但我想訪問此主。任何想法如何有效地跟蹤主要功能評估的數量?

+3

'INT PRNT(){靜態INT NUM = 0;返回num; }' – DeiDei

+2

您需要在任何函數之外聲明'static int num = 0;',以便它也可以從'main'函數中看到,否則它的作用域/可見性僅限於定義它的函數,即使它是靜態的變量。此處的靜態隻影響變量的生命週期,而不影響其範圍/可見性。 – nbro

+0

@DeiDei實際的prnt()函數是一個返回一個double值 – Morpheus

回答

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實際上是一個計數器,並通過在你需要調用的函數。

+0

非常感謝您的回答。這對我來說似乎有點複雜,但我會試着去理解它。再次感謝 :) – Morpheus

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; 

} 

我有點不能確定這是否是最好的方式,或者是可以做到更好一點。

貌似有更好的方法來做到這一點..

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; 
}