调用 C++ 的静态成员函数 STL容器的value_type

发布于 2024-07-06 10:13:33 字数 756 浏览 4 评论 0原文

我试图弄清楚为什么以下内容不起作用。 我有一个 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

裸钻 2024-07-13 10:13:33

您正在通过变量实例而不是变量类型访问 value_type。

方法 1 - 这有效:

typedef std::vector<Vector> MyVector;
MyVector v;
unsigned u = MyVector::value_type::Dim();

方法 2 - 或者这样:

std::vector<Vector> v;
unsigned u = std::vector<Vector>::value_type::Dim();

如果您像方法 1 那样键入定义,则不会对向量模板参数的假设进行硬编码,并且会编写干净的代码。


编辑:按照问题所有者的要求进行扩展以解释此问题的行为:

范围解析运算符::具有更高的优先级 高于任何其他 C++ 运算符。 这包括来自对象 . 运算符的成员访问。 因此,当您编写类似以下内容时:

unsigned u= v.value_type::Dim();

这将解析为以下 C++ 代码:

unsigned u = v.SVector<double, 2>::Dim();

最终首先解析的是 SVector::Dim() 部分。 这将强制通过变量 v 声明的向量实例具有名为 SVector 的模板化内部类。 因为这种情况不会发生,所以会导致错误:

error C2039: 'SVector<double,2>' : is not a member of 'std::vector<_Ty>'

对于此模式的每次使用,STL vector 都必须“扩展”(通过变量实例而不是变量类型访问 value_type)。 这不是一个好的解决方案,因为它会导致大量样板文件和不必要且无法维护的代码。 通过遵循上述解决方案,您可以避免这一切,并且可以轻松地执行您想要的操作。

You are accessing the value_type trough the variable instance and not the variable type.

Method 1 - this works:

typedef std::vector<Vector> MyVector;
MyVector v;
unsigned u = MyVector::value_type::Dim();

Method 2 - or this:

std::vector<Vector> v;
unsigned u = std::vector<Vector>::value_type::Dim();

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:

unsigned u= v.value_type::Dim();

this resolves to the following C++ code:

unsigned u = v.SVector<double, 2>::Dim();

and ultimately what is resolved first is the SVector<double, 2>::Dim() part. This would force the vector instance declared trough variable v to have a templatized inner class named SVector. And because this does not happen this results in error:

error C2039: 'SVector<double,2>' : is not a member of 'std::vector<_Ty>'

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文