【问题标题】:Inheriting from std::vector, compiler error? (most vexing parse)从 std::vector 继承,编译器错误? (最令人烦恼的解析)
【发布时间】:2014-06-25 18:53:05
【问题描述】:

对于看到此问题的人: 看看答案并考虑使用:cdecl

为什么下面的代码会报编译错误:

prog.cpp: In function ‘int main()’:
prog.cpp:23:4: error: request for member ‘size’ in ‘a’, which is of non-class type ‘RangeVec<int>(RangeVec<int>)’
  a.size();
    ^

我不明白这段代码有什么问题?

#include <iostream>
#include <vector>

template<typename Type>
class RangeVec: public std::vector<Type> {
    public:

        RangeVec( const RangeVec & v): std::vector<Type>(v){}
        RangeVec( const RangeVec && v): std::vector<Type>(std::move(v)) {}

        RangeVec( const std::vector<Type> &v)
            : std::vector<Type>(v)
        {
            //std::sort(std::vector<Type>::begin(),std::vector<Type>::end());
        }
};

int main(){
    std::vector<int> v;
    RangeVec<int> b(v);
    RangeVec<int> a(  RangeVec<int>(b) );
    a.size(); // b.size() works ???? why??
}

【问题讨论】:

  • 最麻烦的解析,a 是一个函数。
  • 为什么是函数?
  • @Gabriel,阅读 MVP,您就会明白为什么。
  • 这是最近的常见问题解答条目:stackoverflow.com/questions/180172/…

标签: c++ most-vexing-parse


【解决方案1】:
 RangeVec<int> a(  RangeVec<int>(b) );

这是一个函数a 的声明,它返回一个RangeVec&lt;int&gt; 并接受一个名为bRangeVec&lt;int&gt; 类型的参数。这是most vexing parse。您可以使用 C++11 的统一初始化语法来修复它:

 RangeVec<int> a{RangeVec<int>{b}};

或者如果你没有 C++11 编译器,只需引入一对额外的括号:

 RangeVec<int> a((RangeVec<int>(b)))

另请注意,从标准容器派生的是usually a bad idea

【讨论】:

  • 我虽然函数声明看起来如下而不是上面? ---------------------------------------------- RangeVec&lt;int&gt; (a)( RangeVec&lt;int&gt; )
  • @Gabriel 这是一个等价的声明(只是没有参数名称)。
  • 但是RangeVec&lt;int&gt;(b)怎么可能是参数呢?我同意RangeVec&lt;int&gt; b 是一个参数,但带有括号?我不明白
  • @Gabriel 同样,int(x); 是一个名为x 类型为int 的变量的有效声明。 int(((((((x))))))); 也是如此。声明标识符周围可以有任意括号。
  • @Gabriel 当它是一个表达式时,您正在考虑它(在这种情况下,它是类似函数的强制转换符号)。这不是表达式,而是声明。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-14
  • 2019-05-20
相关资源
最近更新 更多