gpt4 book ai didi

c++ - 如何使用可变模板参数保存可变数量的参数?

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:43:46 24 4
gpt4 key购买 nike

我想创建模板类,它可以存储函数指针和 this 函数的参数,以便以后可以使用 this 参数调用该函数。

我想写这个通用的,而不是依赖于参数类型或数量。

这是使用 c++11 的可变参数模板的想法的一部分:

template<class T, typename... Params>
class LazyEvaluation {
private:
// Function to be invoked later
T (*f)(Params...);
// Params for function f
Params... storedParams; // This line is not compilable!
bool evaluated;
T result;
public:
// Constructor remembers function pointer and parameters
LazyEvaluation(T (*f)(Params...),Params... params)
: f(f),
storedParams(params) //this line also cannot be compiled
{}
// Method which can be called later to evaluate stored function with stored arguments
operator T&() {
// if not evaluated then evaluate
if (! evaluated) {
result = f(storedParams...);
evaluated = true;
}
return result;
}
}

如果可能的话,我希望至少让此类的公共(public)接口(interface)类型安全。尽管至少以某种方式完成这项工作更为重要。

我设法以某种方式保存了可变数量的参数。但是我无法将它们传递给函数 f。我会把它写成答案,但我希望您在看到我丑陋的无效尝试之前考虑自己的解决方案。

我正在尝试使用 Microsoft Visual C++ 编译器 2012 年 11 月 CTP (v120_CTP_Nov2012) 编译上面的代码,但如果存在独立于编译器的解决方案,那将是最好的。

谢谢

最佳答案

我是这样解决的:

参数包可以递归扩展并保存每个参数。功能商店应该这样做。它使用一个(两次重载)辅助函数。

template<typename T>
void storeHelperFunction(void*& memory, T last) {
*((T*)memory) = last;
memory = (void*)((char*)memory + sizeof(T));
}

template<typename T, typename... Params>
void storeHelperFunction(void*& memory, T first, Params... rest) {
storeHelperFunction(memory, first);
storeHelperFunction(memory, rest...);
}

template<typename... Params>
void store(void* memory, Params... args) {
// Copy of pointer to memory was done when passing it to this function
storeHelperFunction(memory, args...);
}

函数存储采用指向内存的指针,其中应该保存可变数量的参数。

指针可以指向一些动态分配的内存或更好地指向大小等于sizeof...(Params)的结构。 .这种具有任意大小的结构可以使用模板元编程来构造:

template <int N>
struct allocatorStruct {
char byte1;
allocatorStruct<N-1> next;
};

template <>
struct allocatorStruct<1> {};

我不确定标准是怎么说的,也不知道除微软以外的其他编译器是如何编译它的。但是使用我的编译器,对于任何大于或等于 1 的 N,sizeof(allocatorStruct) 都等于 N。

因此 allocatorStruct<sizeof...(Params)>与 Params 具有相同的大小。

另一种创建与 Params 具有相同大小的东西的方法是使用类型 char [sizeof...(Params)] .这样做的缺点是,当您尝试将这样的数组作为参数传递时,编译器只传递指向该数组的指针。这就是为什么最好使用 allocatorStruct<sizeof...(Params)> 的原因。 .

现在主要思想:

保存函数时我们可以将其转换为:T (*)(allocatorStruct<sizeof...(Params)>) .保存函数的参数时,我们可以将它们保存到 allocatorStruct<sizeof...(Params)> 类型的结构中。 .

参数的大小是相同的。尽管函数指针与函数的类型有关,但函数指向的函数将正确获取其数据。

至少我希望如此。根据调用约定,我预计传递的参数可以重新排序或错误,因为从左到右保存参数和从右到左传递之间存在差异。但事实并非如此。使用 __cdecl 调用约定仅传递第一个参数,而另一个参数丢失。使用其他调用约定,程序停止工作。

我没有花太多时间调试它并查看内存中的数据(在堆栈上)。这至少是正确的方法吗?

关于c++ - 如何使用可变模板参数保存可变数量的参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17996003/

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