gpt4 book ai didi

c++ - 尝试扩展模板参数包时出错

转载 作者:塔克拉玛干 更新时间:2023-11-03 07:12:39 25 4
gpt4 key购买 nike

我正在尝试使用可变参数模板将参数类型存储到成员函数中。我试图实现这一点的方法是将每种类型与一个键相关联,然后将这个键存储在一个 std::vector 中。创建这个key的代码如下

template <typename T>
class ClassInfo {
public:
inline static void const* GetClassKey() {
static char key;
return &key;
}
};

然后我使用以下代码尝试将 key 存储在 std::vector 中

class WrappedMemberFunction {
void *function_pointer; // Holds the member function pointer
void const* class_type; // Class type key
void const* return_type; // Return type key
std::vector<void const*> parameter_types; // Parameter type keys

void StoreArguments() {}
template <typename Arg, typename... Args>
void StoreArguments() {
parameter_types.push_back(ClassInfo<Arg>::GetClassKey());
StoreArguments<Args...>(); // Error here: No matching member function for call to 'StoreArguments'
}


public:
template <typename Class, typename ReturnType, typename... Args>
WrappedMemberFunction(ReturnType (Class::*member_pointer)(Args...)) {
// Store member pointer as regular old void pointer
function_pointer = (void*&)member_pointer;

// Store class type
class_type = ClassInfo<Class>::GetClassKey();

// Store return type
return_type = ClassInfo<Class>::GetClassKey();

// Store parameter types
StoreArguments<Args...>();
}
};

我遇到的问题是存储每个类键所需的可变递归。我在上面指示的行中收到错误,这是尝试扩展参数包的递归步骤。我在这里做错了什么?

最佳答案

你有:

// function that is not a template
void StoreArguments() {}

// function template that takes N+1 types
template <typename Arg, typename... Args>
void StoreArguments() {
parameter_types.push_back(ClassInfo<Arg>::GetClassKey());

// call function template that takes N types
StoreArguments<Args...>();
}

希望我添加的评论能说明这一点……您正在从采用 N+1 类型的函数模板递归到采用 N 类型的函数模板。基本情况有一个采用 0 种类型的函数模板。你没有那个,你有一个空函数 - 不会被考虑。

您的方法是将您的类型提升为值,因此您的基本情况实际上是一个空函数:

template <class T> struct tag { using type = T; };

void StoreArgumentsImpl() { }

template <typename Arg, typename... Tags>
void StoreArgumentsImpl(tag<Arg>, Tags... tags) {
parameter_types.push_back(ClassInfo<Arg>::GetClassKey());

StoreArgumentsImpl(tags...);
}

template <typename... Args>
void StoreArguments() {
StoreArgumentsImpl(tag<Args>{}...);
}

或者使用 expander trick 在单个函数中完成所有操作:

template <typename... Args>
void StoreArguments() {
using expander = int[];
(void)expander{0,
(void(
parameter_types.push_back(ClassInfo<Args>::GetClassKey())
), 0)...
};
}

或者,在 C++17 中(迫不及待),使用折叠表达式:

template <typename... Args>
void StoreArguments() {
(parameter_types.push_back(ClassInfo<Args>::GetClassKey()), ...);
}

或者,同样在 C++17 中,使用 if constexpr(尽管这不适用于没有参数):

template <typename Arg, typename... Args>
void StoreArguments() {
parameter_types.push_back(ClassInfo<Args>::GetClassKey());

if constexpr(sizeof...(Args) > 0) {
StoreArguments<Args...>();
}
}

关于c++ - 尝试扩展模板参数包时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38491250/

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