明确的 range-v3 decltype 评估为无效?
Explicit range-v3 decltype evaluates to void?
我正在尝试获取范围的显式类型(我可能希望将来将其作为字段存储在 class 中)。但是,出于某种原因,它的计算结果为 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); }
});
}
但实际上,以这种方式存储视图并不是一个好主意。
我正在尝试获取范围的显式类型(我可能希望将来将其作为字段存储在 class 中)。但是,出于某种原因,它的计算结果为 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); }
});
}
但实际上,以这种方式存储视图并不是一个好主意。