使用get函数进行C ++编译时迭代

时间:2018-03-31 11:11:49

标签: c++ templates c++14 variadic-templates template-meta-programming

我想知道是否可以做下一件事。 例如,我有以下带有operator+()构造函数,getter和#include <cstdint> #include <cassert> template <typename T, std::size_t NumEl> class MyContainer { public: // constructor template <typename... Args> MyContainer(Args... tail): values{T(tail)...} { static_assert(sizeof...(Args) == NumEl, "wrong number of arguments"); } template<uint8_t Index> constexpr T& get() { return values[Index]; } constexpr auto operator +(const MyContainer<T, NumEl>& other) { // no idea here return MyContainer<T, NumEl>() ; } private: T values[NumEl]; }; int main() { MyContainer<double, 3> a(0.0, 1.0, 3.0); MyContainer<double, 3> b(1., 2.0, 5.0); assert(a.get<0>() == 0.0); assert(a.get<1>() == 1.0); auto c = a + b; assert(c.get<0>() == 1.0); assert(c.get<1>() == 3.0); assert(c.get<2>() == 8.0); return 0; } 的模板类。

operator+()

我希望使用get()函数和variatic构造函数来实现T sumVals[NumEl] = {0}; for (int i = 0; i < NumEl; ++i) { sumVals = values[i] + other.get<i>(); ,我坚持到这里。如果我将使用sum创建一个数组,我知道如何为variadic构造函数创建一个元组。但我不能简单地写

get<i>()

由于operator+()产生编译错误。我假设我应该使用递归模板,但不知道如何实现它。

所以,问题是如何在这种情况下实现$("input:checkbox[class="+itemCode+"]:checked").each(function() { alert(itemCode); });

谢谢!

2 个答案:

答案 0 :(得分:1)

嗯......您的代码中存在一些问题。

首先,如果你想要一个constexpr类,并且(我想)constexpr get()方法初始化constexpr变量并检查值编译时间

所以

1)定义constexpr你的构造函数

   template <typename ... Args>
   constexpr MyContainer (Args ... tail): values{T(tail)...}
    { static_assert(sizeof...(Args) == NumEl, "wrong # of args"); }

或者您无法创建constexpr

类型的MyContainer对象

2)定义constexpr get()方法,或者您无法检查编译时constexpr MyContainer

的值

3)您还必须将get()定义为const并返回T const &

  template <std::uint8_t Index>
  constexpr T const & get() const
   { return values[Index]; }

或者您不能将get()const对象一起使用(而constexpr对象也是const

现在,在main()中,您可以将ab定义为constexpr个对象

constexpr MyContainer<double, 3> a(0.0, 1.0, 3.0);
constexpr MyContainer<double, 3> b(1., 2.0, 5.0);

并使用static_assert()

验证vales,编译时间
static_assert(a.get<0>() == 0.0, "!");
static_assert(a.get<1>() == 1.0, "!");

现在是总和。

通常operator+()被定义为函数(需要时为friend函数),而不是作为类的方法。

我建议创建一个已分派的private constexpr构造函数,如下所示

  template <std::size_t ... Is>
  constexpr MyContainer (MyContainer const & mc1,
                         MyContainer const & mc2, 
                         tagAdd const &,
                         std::index_sequence<Is...> const &)
     : values{ mc1.values[Is] + mc2.values[Is] ... }
   { }

其中tagAdd是内部结构

  struct tagAdd { };

允许区分此构造函数与类似构造函数(可能是a - b的构造函数,a * b的构造函数等)。

您的friend operator+()(在课程中定义)只是

  friend constexpr MyContainer operator+ (MyContainer const & mc1,
                                          MyContainer const & mc2)
   { return {mc1, mc2, tagAdd{}, std::make_index_sequence<NumEl>{}}; }

以下是一个完整的工作示例

#include <utility>
#include <iostream>

template <typename T, std::size_t NumEl>
class MyContainer
 {
   private:
      struct tagAdd { };

      T values[NumEl];

      template <std::size_t ... Is>
      constexpr MyContainer (MyContainer const & mc1,
                             MyContainer const & mc2, 
                             tagAdd const &,
                             std::index_sequence<Is...> const &)
         : values{ mc1.values[Is] + mc2.values[Is] ... }
       { }

   public:
      template <typename ... Args>
      constexpr MyContainer (Args ... tail): values{T(tail)...}
       { static_assert(sizeof...(Args) == NumEl, "wrong # of args"); }

      template <std::uint8_t Index>
      constexpr T const & get() const
       { return values[Index]; }

      friend constexpr MyContainer operator+ (MyContainer const & mc1,
                                              MyContainer const & mc2)
       { return {mc1, mc2, tagAdd{}, std::make_index_sequence<NumEl>{}}; }
 };

int main ()
 {
   constexpr MyContainer<double, 3> a(0.0, 1.0, 3.0);
   constexpr MyContainer<double, 3> b(1., 2.0, 5.0);

   static_assert(a.get<0>() == 0.0, "!");
   static_assert(a.get<1>() == 1.0, "!");

   constexpr auto c = a + b;

   static_assert(c.get<0>() == 1.0, "!");
   static_assert(c.get<1>() == 3.0, "!");
   static_assert(c.get<2>() == 8.0, "!");
 }

答案 1 :(得分:0)

解决方案是在values[]中使用get<>()代替operator+()。要声明一个临时对象来保存总和,只需复制*this

constexpr auto operator +(const MyContainer<T, NumEl>& other) {
    auto sumVals = *this;
    for (std::size_t i = 0; i < NumEl; ++i) {
        sumVals.values[i] += other.values[i];
    return sumVals;
}