C++ 显式range-v3 decltype的计算结果为void?
我试图获得一个范围的显式类型(将来可能希望将其存储为类中的字段)。但是,由于某种原因,它的计算结果为C++ 显式range-v3 decltype的计算结果为void?,c++,c++17,range-v3,C++,C++17,Range V3,我试图获得一个范围的显式类型(将来可能希望将其存储为类中的字段)。但是,由于某种原因,它的计算结果为无效 #include <iostream> #include <set> #include <range/v3/view/transform.hpp> class Alpha { public: int x; }; class Beta : public Alpha { }; class Foo { public: std::set<Al
无效
#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++版本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
std::declval() //^这里应该是左值
- 视图转换信息编码在模板参数中。因此,如果使用
表示类型,则表达式的类型应该完全相同。lambda不行view::transform(std::function())
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-Foo{
公众:
std::集s;
使用RangeReturn=decltype(std::declval()| ranges::v3::view::transform(std::function());
测距仪();
};
Foo::RangeReturn Foo::r(){
返回s | ranges::v3::view::transform(std::function{
[](Alpha*a){返回静态_cast(a);}
});
}
但实际上,以这种方式存储视图不是一个好主意。@CygnusX1它可能是基于观点的。视图的类型是用户不应该关心的实现细节。我不知道您为什么要存储该类型,我会使用
auto
作为返回类型,让编译器进行推断。具有讽刺意味的是,我需要该类型的原因与此完全相同。函数体是一个实现细节,我想把它移到cpp文件中。但这使得声明站点的返回类型没有任何可扣除的内容,因此它不能是自动的。
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); }
});
}