在编译时选择一个变量

Select a variable at compile-time

本文关键字:一个 变量 编译 选择      更新时间:2023-10-16

我希望能够通过布尔来指定我需要在编译时间使用的两个变量中的两个变量,所有这些都不直接sfinae 。只有一个功能,类似于std::conditional,但不返回类型。

所以例如在test中,我想拥有

class test
{
    template <class T, bool first, MAGIC_HAPPENS var>
    void apply_it(T &t)
    {
        for (auto &p : var) p.apply(t);
    }
    std::vector<myfunction> var1;
    std::vector<myfunction> var2;
}

使用很简单:如果我指定first == true,则应使用var == var1应用循环,否则var == var2

可能吗?

只是为了娱乐(*), minimal c 17(**)对当前代码段的修改可能是

class test
{
    std::vector<myfunction> var1;
    std::vector<myfunction> var2;
    template <class T, bool first, std::vector<myfunction> test::*var = first ? &test::var1 : &test::var2 >
    void apply_it(T &t)
    {
        for (auto &p : this->*var) p.apply(t);
    }
};

(*)我没有看到这样的事情比其他建议的解决方案更可取的情况...

(**)据我所知,由于模板的连锁要求非类型指针参数...

,这需要C 17

for C 17及以上:

class test
{
    template <class T, bool first>
    void apply_it(T &t)
    {
        if constexpr (first)
        {
            for (auto &p : var1) p.apply(t);
        }
        else
        {
            for (auto &p : var2) p.apply(t);
        }
    }
    std::vector<myfunction> var1;
    std::vector<myfunction> var2;
}

if constexpr如果条件为constexpr,则在编译时间进行评估,模板参数就是这种情况。

您可以在C 11中使用指向数据成员的指针:

class test
{
    template <class T, bool first>
    void apply_it(T &t)
    {
        constexpr auto var = first ? &test::var1 : &test::var2;
        for (auto &p : this->*var) p.apply(t);
    }
    std::vector<myfunction> var1;
    std::vector<myfunction> var2;
}
template<std::size_t I, class...Args>
decltype(auto) pick( Args&&... args ) {
  return std::get<I>( std::forward_as_tuple( std::forward<Args>(args)... ) );
}

pick在列表中选择某些内容。

class test
{
  template <bool first, class T>
  void apply_it(T&& t)
  {
    auto&& var = pick<first?0:1>(var1, var2);
    for (auto&& p : var)
      p.apply(t);
  }
  std::vector<myfunction> var1;
  std::vector<myfunction> var2;
};

我在复制粘贴时也做出了一些小改进。