我想做的事:
创建一个“指令集”对象
我尝试通过在可变参数类上使用继承来实现这一点,以便可以使用递归来存储正确类型的每条指令;然后,指向“InstructionSet<>”类型的指针可以在其上使用虚拟函数,以便能够访问继承的底部,并在该对象上递归。
//Define recursively
template<typename...Args> requires (is_instruction_type<Args> && ...)
class InstructionSet;
//Base
template<>
class InstructionSet<>
{
public:
InstructionSet() {};
virtual ~InstructionSet() {};
template<typename U>
auto extract()
{
return extractHelper()->extract();
};
protected:
virtual InstructionSet<>* extractHelper();
};
//Recur
template<typename T, typename ...Rest> requires is_instruction_type<T>
class InstructionSet<T, Rest...> : public InstructionSet<Rest...>
{
public:
InstructionSet(T&& t, Rest&&...rest);
InstructionSet(T&& t, InstructionSet<Rest...>&& set);
virtual ~InstructionSet() {};
template<typename U> requires std::same_as<T, U>
auto extract();
template<typename U> requires !std::same_as<T, U>
auto extract();
virtual InstructionSet<T, Rest...>* extractHelper()
{
return this;
};
private:
T _instruction;
};
template<typename T, typename ...Rest> requires is_instruction_type<T>
inline InstructionSet<T, Rest...>::InstructionSet(T&& t, Rest&& ...rest) : InstructionSet<Rest...>(std::forward<Rest>(rest)...),
_instruction(std::forward<T>(t))
{
}
template<typename T, typename ...Rest> requires is_instruction_type<T>
inline InstructionSet<T, Rest...>::InstructionSet(T&& t, InstructionSet<Rest...>&& set)
{
_instruction = std::forward<T>(t);
std::construct_at((InstructionSet<Rest...>*)this, std::move(set));
}
template<typename T, typename ...Rest> requires is_instruction_type<T>
template<typename U> requires std::same_as<T, U>
auto InstructionSet<T, Rest...>::extract<U>()
{
return InstructionSet(_instruction, std::move(((InstructionSet<Rest...>*)this)->extract()));
}
template<typename T, typename ...Rest> requires is_instruction_type<T>
template<typename U> requires (!std::same_as<T, U>)
auto InstructionSet<T, Rest...>::extract<U>()
{
return ((InstructionSet<Rest...>*)this)->extract();
}
我有两个问题:
我尝试了包含/排除尖括号的不同组合,并尝试将函数定义移动到类内部,但都抛出错误。
我认为我了解具有类型定义和静态变量的类的 SFINAE 基础知识,但是对于更复杂的类,我感到困惑,并且似乎找不到很多示例。
我认为你可以通过不进行专业化并使用
std::tuple
来简化它。
示例:
template <class... Ts>
requires(is_instruction_type<Ts> && ...)
class InstructionSet {
public:
template <class... Us>
InstructionSet(Us&&... us) : _instructions{std::forward<Us>(us)...} {}
virtual ~InstructionSet() = default;
template <std::size_t... Is> // extract by index
InstructionSet<std::tuple_element_t<Is, std::tuple<Ts...>>...> extract();
template <class... Us> // extract by unique types
InstructionSet<Us...> extract();
private:
std::tuple<Ts...> _instructions;
};
template <class... Ts>
requires(is_instruction_type<Ts> && ...)
template <std::size_t... Is>
InstructionSet<std::tuple_element_t<Is, std::tuple<Ts...>>...>
InstructionSet<Ts...>::extract() {
return {std::get<Is>(_instructions)...};
}
template <class... Ts>
requires(is_instruction_type<Ts> && ...)
template <class... Us>
InstructionSet<Us...>
InstructionSet<Ts...>::extract() {
return {std::get<Us>(_instructions)...};
}