fre*_*low 5 c++ lambda decltype template-meta-programming c++11
在算法中,我想创建一个lambda,它通过引用到const接受一个元素:
template<typename Iterator>
void solve_world_hunger(Iterator it)
{
auto lambda = [](const decltype(*it)& x){
auto y = x; // this should work
x = x; // this should fail
};
}
Run Code Online (Sandbox Code Playgroud)
编译器不喜欢这段代码:
错误:»const«-qualifier不能应用于»int&«(从德语手动翻译)
然后我意识到这decltype(*it)已经是一个参考,当然那些不可能const.如果我删除了const,代码编译,但我想x = x失败.
让我们相信程序员(这是我)一分钟,并摆脱const显而易见的&,由于参考折叠规则而被删除,无论如何.但等等,decltype(*it)实际上是保证是一个参考,还是我应该添加明确&的安全方面?
如果我们不信任程序员,我可以考虑两种解决方案来解决问题:
(const typename std::remove_reference<decltype(*it)>::type& x)
(const typename std::iterator_traits<Iterator>::value_type& x)
Run Code Online (Sandbox Code Playgroud)
你可以自己决定哪一个更丑.理想情况下,我想要一个不涉及任何模板元编程的解决方案,因为我的目标受众之前从未听说过.所以:
问题1:decltype(*it)&总是一样的decltype(*it)吗?
问题2:如何在没有模板元编程的情况下通过引用传递元素?
问题 1:不,对 InputIterator 的要求仅仅是可*it转换为 T(“迭代器要求”中的表 72)。
decltype(*it)例如,const char&对于一个 为 的迭代器来说value_type也是如此int。或者也可能是int。或者double。
usingiterator_traits不等于 using decltype,决定你想要哪个。
出于同样的原因,auto value = *it;不一定会为您提供具有迭代器值类型的变量。
问题 2:可能取决于您所说的模板元编程的含义。
如果使用的特征类型是 TMP,那么没有 TMP 就无法指定“对迭代器的值类型的 const 引用”,因为iterator_traits这是访问任意迭代器的值类型的唯一方法。
如果你想 const-ify 那么decltype这个怎么样?
template<typename Iterator>
void solve_world_hunger(Iterator it)
{
const auto ret_type = *it;
auto lambda = [](decltype(ret_type)& x){
auto y = x; // this should work
x = x; // this should fail
};
}
Run Code Online (Sandbox Code Playgroud)
您可能必须捕获ret_type才能使用其类型,我目前无法轻松检查。
不幸的是,它会额外取消引用迭代器。您可能可以编写一些聪明的代码来避免这种情况,但聪明的代码最终将成为 的替代版本remove_reference,即 TMP。
| 归档时间: |
|
| 查看次数: |
274 次 |
| 最近记录: |