我正在尝试获取当前类包装器的可变参数的子集,以实例化一个新的包装器
目前我有这个:
// Reference: https://stackoverflow.com/questions/27941661/generating-one-class-member-per-variadic-template-argument
// Template specialization
template<typename T, typename... Next> class VariadicClass;
// Base case extension
template <typename T>
class VariadicClass<T> {
private:
T value_;
protected:
void SetField(T & value) {
value_ = value;
}
T & GetField() {
return value_;
}
};
// Inductive case
template <typename T, typename ... Next>
class VariadicClass : public VariadicClass<T>, public VariadicClass<Next...> {
public:
// Copy the values into the variadic class
template <typename F>
void Set(F f) {
this->VariadicClass<F>::SetField(f);
}
// Retrieve by reference
template <typename F>
F & Get() {
return this->VariadicClass<F>::GetField();
}
};
我要实现的目标是:
[C]: A subset of Args...
VariadicClass<[C]> * Filter(VariadicClass<Args...> input) {
return new VariadicClass<[C]>(GetSubsetFrom(input, [C]));
}
VariadicClass<int, bool, char> class1;
VariadicClass<int, bool> * variadic = Filter(class1);
您可以假设每个类型在可变参数类中只有一次,并且我将始终要求提供当前可变参数类型的子集。我不知道这在C++ 11中当前是否可行?
谢谢您的帮助。
最佳答案
在我看来,您正在尝试重新发明轮子(在这种情况下,“wheel”为std::tuple
)。
无论如何,你的要求对我来说似乎很简单
template <typename ... As1, typename ... As2>
VariadicClass<As1...> * Filter(VariadicClass<As2...> in)
{
using unused = int[];
auto ret = new VariadicClass<As1...>();
(void)unused { 0, (ret->template Set<As1>(in.template Get<As1>()), 0)... };
return ret;
}
我看到的问题是
As1...
类型(返回的VariadicClass
的类型)不能由返回的值推导,因此您不能编写 VariadicClass<int, bool> * variadic = Filter(class1);
您必须显式调用
As1...
的Filter()
类型,因此 VariadicClass<int, bool> * variadic = Filter<int, bool>(class1);
或者,也许更好
auto variadic = Filter<int, bool>(class1);
以下是完整的编译示例
#include <iostream>
template <typename, typename...>
class VariadicClass;
template <typename T>
class VariadicClass<T>
{
private:
T value_;
protected:
void SetField (T & value)
{ value_ = value; }
T & GetField ()
{ return value_; }
};
template <typename T, typename ... Next>
class VariadicClass : public VariadicClass<T>, public VariadicClass<Next...>
{
public:
template <typename F>
void Set (F f)
{ this->VariadicClass<F>::SetField(f); }
template <typename F>
F & Get()
{ return this->VariadicClass<F>::GetField(); }
};
template <typename ... As1, typename ... As2>
VariadicClass<As1...> * Filter(VariadicClass<As2...> in)
{
using unused = int[];
auto ret = new VariadicClass<As1...>();
(void)unused { 0, (ret->template Set<As1>(in.template Get<As1>()), 0)... };
return ret;
}
int main()
{
VariadicClass<int, bool, char> c1;
c1.Set<int>(42);
c1.Set<bool>(true);
c1.Set<char>('Z');
auto pC2 = Filter<int, bool>(c1);
std::cout << pC2->Get<int>() << std::endl;
std::cout << pC2->Get<bool>() << std::endl;
delete pC2;
}
主题外的非请求建议:您正在使用C++ 11,因此...尝试避免直接使用指针,而尝试使用智能指针(
std::unique_ptr
,std::shared_ptr
等)。关于c++ - 可变参量子集,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/57566656/