如何解决如何在模板中使用迭代器值?
考虑以下代码:
#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)>();
});
}
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 举报,一经查实,本站将立刻删除。