调用 C++ 的静态成员函数 STL容器的value_type
我试图弄清楚为什么以下内容不起作用。 我有一个 std::vector 并且我想调用它包含的 value_type 的静态成员函数,如下所示:
std::vector<Vector> v;
unsigned u = v.value_type::Dim();
其中 Vector 实际上是模板化类型的 typedef:
template <typename T, unsigned U> class SVector;
typedef SVector<double, 2> Vector; //two-dimensional SVector containing doubles
并且静态成员函数 Dim() 实际上内联了向量。
现在编译器返回一条错误消息:
error: ‘SVector<double, 2u>’ is not a base of
‘std::vector<SVector<double, 2u>, std::allocator<SVector<double, 2u> > >
这让我很困惑。 我可以用
unsigned u = Vector::Dim();
和 替换明显有问题的行,但它显然很难看,因为它硬编码了关于 v 的 value_type 的假设... 谢谢!
I'm trying to get my head around why the following doesn't work. I have a std::vector and I want to call a static member function of it's contained value_type like so:
std::vector<Vector> v;
unsigned u = v.value_type::Dim();
where Vector is in fact a typedef for a templated type:
template <typename T, unsigned U> class SVector;
typedef SVector<double, 2> Vector; //two-dimensional SVector containing doubles
and the static member function Dim() actually inlines the dimensionality U of the Vector.
Now the compiler returns an error message saying:
error: ‘SVector<double, 2u>’ is not a base of
‘std::vector<SVector<double, 2u>, std::allocator<SVector<double, 2u> > >
which puzzles me. I can replace the apparently offending line by
unsigned u = Vector::Dim();
and that works, but is obviously ugly as it hardcodes assumptions about the value_type of v...
Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您正在通过变量实例而不是变量类型访问 value_type。
方法 1 - 这有效:
方法 2 - 或者这样:
如果您像方法 1 那样键入定义,则不会对向量模板参数的假设进行硬编码,并且会编写干净的代码。
编辑:按照问题所有者的要求进行扩展以解释此问题的行为:
范围解析运算符
::
具有更高的优先级 高于任何其他 C++ 运算符。 这包括来自对象.
运算符的成员访问。 因此,当您编写类似以下内容时:这将解析为以下 C++ 代码:
最终首先解析的是
SVector::Dim()
部分。 这将强制通过变量v
声明的向量实例具有名为 SVector 的模板化内部类。 因为这种情况不会发生,所以会导致错误:对于此模式的每次使用,STL
vector
都必须“扩展”(通过变量实例而不是变量类型访问 value_type)。 这不是一个好的解决方案,因为它会导致大量样板文件和不必要且无法维护的代码。 通过遵循上述解决方案,您可以避免这一切,并且可以轻松地执行您想要的操作。You are accessing the value_type trough the variable instance and not the variable type.
Method 1 - this works:
Method 2 - or this:
If you typedef like on method 1 you do not hardcode assumptions on vector template parameter and you write clean code.
Edit: Expanded to explain the behavior for this issue as requested by question owner:
The scope resolution operator
::
has higher precedence than any other C++ operator. This includes the Member access from an object.
operator. Thus when you write something like:this resolves to the following C++ code:
and ultimately what is resolved first is the
SVector<double, 2>::Dim()
part. This would force the vector instance declared trough variablev
to have a templatized inner class named SVector. And because this does not happen this results in error:STL
vector
would have to be "expanded" for each usage of this pattern (accessing value_type trough variable instance and not variable type). This is not a good solution as it leads to lots of boilerplate and unnecessary and unmaintainable code. By following the above mentioned solutions you avoid all this and can easily do what you wanted.