gpt4 book ai didi

python - 作为参数的嵌套模板函数

转载 作者:行者123 更新时间:2023-11-28 05:43:16 28 4
gpt4 key购买 nike

在 Python 中,有一种非常简单的方法来装饰函数,这样您就可以在函数之前和/或之后添加额外的功能。在最简单的形式中,它看起来像这样:

from random import SystemRandom
from time import time
import functools

rdev = SystemRandom()

def time_function(func):
@functools.wraps(func)
def run(*args, **kwargs):
start = time()
ret = func(*args, **kwargs)
print("Took {:0.5f}s".format(time()-start))
return ret
return run

@time_function
def foo():
x = [rdev.randint(1, 1000) for _ in range(10000)]
sorted(x)

foo() # prints "Took 0.04239s"

我想用 C++ 编写具有类似功能的东西。我想将具有任意参数和返回类型的函数传递给函数并让它执行一些操作。这是我想出的:

#ifndef TIMEIT_H
#define TIMEIT_H
#include <string>
#include <functional>
#include <iostream>
#if defined(_WIN32)
#include <Windows.h>
namespace timeit {
unsigned long gettime(void) {
return GetTickCount();
}
}
#elif defined(__linux__)
namespace timeit{
unsigned long gettime(void) {
return 0; // implement later
}
}
#endif

namespace timeit {
template <typename> struct timer_s;

template<typename... Args> // this is required for any void function
struct timer_s<void(Args ...)> {
std::function<void(Args ...)> func;
timer_s(std::function<void(Args ...)> f) : func{ f } {}
void operator()(unsigned long &time, Args ... args) {
unsigned long start = gettime();
func(args ...);
time = gettime() - start;
return;
}
};

template <typename T, typename... Args> // this is for any other return type
struct timer_s<T(Args ...)> {
std::function<T(Args ...)> func;
timer_s(std::function<T(Args ...)> f) : func{ f } { }
T operator()(unsigned long &time, Args ... args) {
unsigned long start = gettime();
T ret = func(args ...);
time = gettime() - start;
return ret;
}
};

template<typename T, typename... Args>
timer_s<T(Args...)> timer(T(*func)(Args ...)) {
return timer_s<T(Args ...)>(std::function<T(Args ...)>(func));
}
}
#endif//TIMEIT_H

这工作得很好。例如,我几乎可以使用以下函数为任何函数计时:

static std::random_device rdev;

unsigned int foo(size_t size){
std::vector<unsigned int> nums(size);
std::mt19937 rand(rdev());
std::generate(nums.begin(), nums.end(), rand);
std::sort(nums.begin(), nums.end());
return nums.back(); // return largest number
}

int main(){
//foo(0xffff); // normal call
unsigned long foo_time = 0;
auto t_foo = timeit::timer(foo);
unsigned int largest = t_foo(foo_time, 0xffff); // stores time
std::cout << "Took " << foo_time << "ms\nLargest number: " << largest << "\n";
return 0;
}

当我尝试直接对诸如 std::sort 之类的模板函数计时时,问题就出现了。如果我指定确切的类型,我只能这样做。我想我想知道 C++ 是否能够进行嵌套模板推导。我希望它推断出我正在使用哪种形式的 std::sort 并动态更改 t_sort 的实现:

我现在在做什么:

static std::random_device rdev;

int main(){
std::vector<unsigned int> nums(size);
std::mt19937 rand(rdev());
std::generate(nums.begin(), nums.end(), rand);
auto t_sort = timeit::timer(std::sort<std::vector<unsigned int>::iterator>);
unsigned long sort_time = 0;
t_sort(sort_time, nums.begin(), nums.end());
}

我想要什么:

static std::random_device rdev;

int main(){
std::vector<unsigned int> nums(size);
std::mt19937 rand(rdev());
std::generate(nums.begin(), nums.end(), rand);
auto t_sort = timeit::timer(std::sort); // this line is different
unsigned long sort_time = 0;
t_sort(sort_time, nums.begin(), nums.end());
}

这可能吗?我最初的 react 可能不是,但如果不是,为什么?

最佳答案

std::sort 不是函数而是函数模板,

一个解决方案是用任何 accept Functor 代替:

namespace timeit {

template <typename Functor>
struct timer_s {
Functor func;
double time = 0;
timer_s(Functor f) : func{ f } {}

template <typename ... Ts>
auto operator()(Ts ... args) {
struct Finally {
~Finally() {
time = std::chrono::duration_cast<std::chrono::milliseconds>
(std::chrono::system_clock::now() - start).count();
}
double& time;
std::chrono::time_point<std::chrono::system_clock> start;
} finally{time, std::chrono::system_clock::now()};
return func(std::forward<Ts>(args)...);
}
};

template<typename F>
timer_s<F> timer(F f) {
return timer_s<F>(f);
}
}

然后调用它:

// Generic lambda to wrap std::sort and call the correct one.
auto t_sort = timeit::timer([](auto b, auto e){ return std::sort(b, e); });

std::vector<int> v {4, 8, 23, 42, 15, 16};

t_sort(v.begin(), v.end());

Demo

关于python - 作为参数的嵌套模板函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36707785/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com