我正在尝试获取范围的显式类型(将来我可能想将其存储为类中的字段)。然而,由于某种原因,它评估为void
?
#include <iostream>
#include <set>
#include <range/v3/view/transform.hpp>
class Alpha {
public:
int x;
};
class Beta : public Alpha {
};
class Foo {
public:
std::set<Alpha*> s;
using RangeReturn = decltype(std::declval<std::set<Alpha*>>() | ranges::v3::view::transform(std::function<Beta*(Alpha*)>()));
RangeReturn r();
};
Foo::RangeReturn Foo::r() {
return s | ranges::v3::view::transform([](Alpha* a) { return static_cast<Beta*>(a); });
}
int main() {
}
当使用 g++ -std=c++17 编译时,它给出
main.cpp:24:88: error: return-statement with a value, in function returning 'void' [-fpermissive]
(g++版本g++(Ubuntu 7.3.0-27ubuntu1~18.04)7.3.0)
我在 Visual Studio 2017 v. 15.9 上遇到类似的错误
这个问题是我另一个问题的延续:如何将范围存储为类中的字段?但更具体,我认为它应该分开。
您的代码不起作用,因为:
-
range/v3 视图禁用右值视图,因为这会导致悬空引用。因此在你的declval()
,您还应该使用左值:
std::declval<std::set<Alpha*>&>()
// ^ here should be lvalue
视图变换信息被编码在模板参数内。所以如果你使用view::transform(std::function<Beta*(Alpha*)>())
为了表示类型,您的表达式应该具有完全相同的类型。 lambda 不行。
一个工作版本是:
class Foo {
public:
std::set<Alpha*> s;
using RangeReturn = decltype(std::declval<std::set<Alpha*>&>() | ranges::v3::view::transform(std::function<Beta*(Alpha*)>()));
RangeReturn r();
};
Foo::RangeReturn Foo::r() {
return s | ranges::v3::view::transform(std::function<Beta*(Alpha*)>{
[](Alpha* a) { return static_cast<Beta*>(a); }
});
}
但实际上,以这种方式存储视图并不是一个好主意。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)