2016-09-06 2 views
1

다른 함수가 실행되는 데 걸리는 시간을 기록하는 일반 함수를 구현하려고합니다.완벽한 전달 템플릿 함수

#include <iostream> 
#include <future> 
#include <thread> 
#include <vector> 
#include <functional> 
#include <numeric> 
#include <memory> 

template<typename Res, typename Func, typename...Args> 
std::pair<Res, double> ftime(Func fun, Args&&... args) 
{ 
    auto start = std::chrono::system_clock::now(); 
    Res res = fun(std::forward<Args>(args)...); 
    std::chrono::duration<double> duration = std::chrono::system_clock::now() - start; 
    return std::make_pair(res, duration.count()); 
} 

int main() 
{ 
    std::vector<int> values (100, 1); 

    auto res = ftime(std::accumulate, values.begin(), values.end(), 0); 
    std::cout << "Sum up " << values.size() << std::endl; 
    std::cout << "Serial sum = " << res.first << " took : " << res.second << std::endl; 
} 

위의 코드는 다음과 같은 오류와 함께 컴파일에 실패 :

sum_1000000.cpp: In function ‘int main()’: 
sum_1000000.cpp:22:68: error: no matching function for call to ‘ftime(<unresolved overloaded function type>, std::vector<int>::iterator, std::vector<int>::iterator, int)’ 
    auto res = ftime(std::accumulate, values.begin(), values.end(), 0); 
                    ^
sum_1000000.cpp:10:24: note: candidate: template<class Res, class Func, class ... Args> std::pair<Res, double> ftime(Func, Args&& ...) 
std::pair<Res, double> ftime(Func fun, Args&&... args) 
         ^
sum_1000000.cpp:10:24: note: template argument deduction/substitution failed: 
sum_1000000.cpp:22:68: note: couldn't deduce template parameter ‘Res’ 
    auto res = ftime(std::accumulate, values.begin(), values.end(), 0); 

를 지금까지 내가 이해 한, 컴파일러는 표준 : acumulate 함수의 템플릿 유형을 indentify 수 없습니다. 내가 도대체 ​​뭘 잘못하고있는 겁니까?

고맙습니다.

+0

나는 어떻게 컴파일러가 템플릿 매개 변수'Res'를 추론 할 수 있는지 보지 못했다. –

답변

2

코드에 몇 가지 문제점이 있습니다.

먼저 함수 반환 유형을 추론 :

template<typename Func, typename...Args> 
auto ftime(Func fun, Args&&... args) -> std::pair<decltype(fun(std::forward<Args>(args)...)), double> 
{ 
    auto start = std::chrono::system_clock::now(); 
    auto res = fun(std::forward<Args>(args)...); 
    std::chrono::duration<double> duration = std::chrono::system_clock::now() - start; 
    return std::make_pair(res, duration.count()); 
} 

std::accumulate 함수, 오히려 템플릿 아니다. 가장 쉬운 람다로 호출을 래핑하는 것입니다 : 그것은 accumulate에 대한 템플릿 paramters을 추론 할 수 없기 때문에

auto res = ftime([&values]() { return std::accumulate(values.begin(), values.end(), 0); }); 
1

컴파일러뿐만 아니라 템플릿의 Res을 추론 할 수 없습니다.

#include <utility> 
#include <chrono> 
#include <vector> 
#include <numeric> 
#include <iostream> 

template<typename Func, typename...Args> 
auto invoke_timed(Func&& fun, Args&&... args) -> 
    std::pair<decltype(std::forward<Func>(fun)(std::forward<Args>(args)...)), 
    std::chrono::system_clock::duration::rep> 
{ 
    auto start = std::chrono::system_clock::now(); 
    auto res = std::forward<Func>(fun)(std::forward<Args>(args)...); 
    return std::make_pair(res, (std::chrono::system_clock::now() - start).count()); 
} 

int main() 
{ 
    std::vector<int> values(100, 1); 
    auto res = invoke_timed(std::accumulate<std::vector<int>::iterator, int>, 
    values.begin(), values.end(), 0); 

    std::cout << res.first << ", " << res.second << "\n"; 
    return 0; 
} 
+0

왜 'Func'에 대한 올바른 참조를 사용하고 있습니까? –

+0

@GiuseppePes : 오른쪽/왼쪽 값 참조가 아니라 전달 참조가 있으며 전달 된 함수 객체의 값 범주를 보존하기 위해 매개 변수가 사용자가 작성한 방식으로 복사 될 큰 함수 객체를 허용하기 때문에 사본을 피하기 위해이 함수를 사용합니다 그것. – Pixelchemist

+0

알겠습니다. Aren t 전달 참조 및 평가 동일한 참조? –