微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在模板中使用迭代器值?

如何解决如何在模板中使用迭代器值?

考虑以下代码

#include <iostream>

enum class E
{
    A,B
};

template<E e> int f();

template<> int f<E::A>(){ return 1; }
template<> int f<E::B>(){ return 2; }

int main()
{
  for( const E i : {E::A,E::B} )
  {
      std::cout << f<i>() << "\n";
  }
}

这无法编译,因为 i 没有用常量表达式初始化。是否有可能使代码的这种想法起作用?

解决方法

这是非常相关的:Why isn't a for-loop a compile-time expression?

i 在循环中不是常量表达式。但是,通过从 this answer 窃取,可以使您的代码在循环内调用 f<i>。这不是您直接要求的,因为建议的解决方案是针对基于 size_t 索引的循环而不是迭代器,但它确实为枚举的所有值调用了 f<i>

#include <iostream>
#include <utility>

// your code

enum class E
{
    A,B
};

template<E e> int f();

template<> int f<E::A>(){ return 1; }
template<> int f<E::B>(){ return 2; }

// https://stackoverflow.com/a/47563100/4117728

template<std::size_t N>
struct num { static const constexpr auto value = N; };

template <class F,std::size_t... Is>
void for_(F func,std::index_sequence<Is...>)
{
  using expander = int[];
  (void)expander{0,((void)func(num<Is>{}),0)...};
}

template <std::size_t N,typename F>
void for_(F func)
{
  for_(func,std::make_index_sequence<N>());
}

// emulate constexpr for (size_t i=0;i<2;++i) f<i>();    

int main()
{
  for_<2>([&] (auto i) {      
    std::cout << f<static_cast<E>(decltype(i)::value)>();
  });
}

Output

12

对于您的实际问题,可能有一个更简单的解决方案。您的字面问题的答案是:不。当 f<i> 不是编译时常量时,您不能调用 i。有关详细说明,请参阅上述问答。

,

编译器无法在对 f<i>() 的调用中推断出 i。这是因为编译发生在运行时之前,并且 i 的值仅在运行时可用。您可以通过添加翻译器来解决此问题。

#include <iostream>

enum class E
{
    A,B
};

template<E e> int f();

template<> int f<E::A>(){ return 1; }
template<> int f<E::B>(){ return 2; }

int bar(E e)
{
  int retval = 0;
  switch(e)
  {
    case E::A:
    {
      return f<E::A>();
      break;
    }
    case E::B:
    {
      return f<E::B>();
      break;
    }
    default:
    {
      break;
    }
  }
  return retval;
}

int main()
{
  for( const E i : {E::A,E::B} )
  {
      std::cout << bar(i) << "\n";
  }

  return 0;
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。