继承自std :: vector,编译错误?(最令人烦恼的解析)

Gab*_*iel 4 c++ most-vexing-parse

对于看到这个问题的人:看看答案并考虑使用: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();
    ^
Run Code Online (Sandbox Code Playgroud)

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

#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??
}
Run Code Online (Sandbox Code Playgroud)

Jos*_*eld 6

 RangeVec<int> a(  RangeVec<int>(b) );
Run Code Online (Sandbox Code Playgroud)

这是一个函数的声明,a它返回一个RangeVec<int>并且接受一个名为btype的参数RangeVec<int>.这是最令人烦恼的解析.您可以使用C++ 11的统一初始化语法来修复它:

 RangeVec<int> a{RangeVec<int>{b}};
Run Code Online (Sandbox Code Playgroud)

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

 RangeVec<int> a((RangeVec<int>(b)))
Run Code Online (Sandbox Code Playgroud)

另请注意,从标准容器派生通常是个坏主意.

  • @Gabriel当它是一个表达式时你正在考虑它(在这种情况下它是类似函数的强制表示法).这不是表达,而是宣言. (3认同)