简体   繁体   English

在编译时选择一个变量

[英]Select a variable at compile-time

I'd like to be able to specify via a boolean which of two variables I need to use at compile time, all of this without direct SFINAE . 我希望能够通过布尔指定我需要在编译时使用哪两个变量,所有这些都没有直接的SFINAE Just one single function, similar to std::conditional but not returning types. 只有一个函数,类似于std::conditional但不返回类型。

So for instance in a class test , I'd like to have 因此,例如在课堂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;
}

The use is simple: if I specify first == true then it should apply the loop with var == var1 , otherwise var == var2 . 使用很简单:如果我指定first == true那么它应该应用var == var1的循环,否则var == var2

Is it possible? 可能吗?

Just for fun(*), a minimal C++17(**) modification to your current code snippet might be 只是为了好玩(*),对当前代码片段的最小 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);
    }
};

(*) I see no situation in which such a thing would be preferable over the other suggested solutions ... (*)我认为没有哪种情况比其他建议的解决方案更可取...

(**) as far as I know, this requires C++17 due to linkage requirement of template non type pointer parameters ... (**)据我所知,由于模板非类型指针参数的链接要求,这需要C ++ 17 ...

For C++17 and above: 对于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 is evaluated at compile time if the condition is constexpr, which is the case for template parameters. if constexpr在编译时被评估,如果条件是constexpr,则模板参数就是这种情况。

You can do that in C++11 with a pointer to data member: 您可以在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 selects at compile time something from a list. 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;
};

I also made some minor improvements while I was copy pasting. 我复制粘贴时也做了一些小的改进。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM