c++ - 可变参数子集

标签 c++ c++11 templates recursion variadic-templates

我正在尝试获取当前类包装器的可变参数的子集以实例化一个新的

目前我有这个:

// 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 中目前是否可行? 感谢您的帮助。

最佳答案

在我看来,您正在尝试重新发明轮子(在这种情况下,“轮子”是 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);

您必须显式调用 Filter()As1... 类型,所以

 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/

相关文章:

c++ - 不同换行符的正则表达式

c++ - C++ 11:将 vector 元素作为线程传递到线程函数中

c++ - 我在板上发现了一个参数包扩展,但我不明白到底发生了什么

C++11 元编程 : check for method existence

c++ - 如何从参数包中获取所有参数的类型?

C++ - 创建二叉搜索树类,旋转后一个节点消失

c++ - C++ 中的 Mergesort 实现错误

c++ - 传递 `std::shared_future` 作为对函数的引用是否合法?

c++ - LLVM 下的非 ASCII wchar_t 文字

c++ - binary_search 总是返回真 C++