2016-03-20 59 views
5

我正在從野牛的語義值構建我的分析數據結構。一種特殊的結構是std::vector<double>。我很好奇,野牛內部人員如何處理移動的語義值。我試着分析C++ M4文件,結果發現:野牛值移動/效率

template <typename Base> 
    inline 
    void 
    ]b4_parser_class_name[::basic_symbol<Base>::move (basic_symbol& s) 
    { 
    super_type::move(s); 
    ]b4_variant_if([b4_symbol_variant([this->type_get()], [value], [move], 
             [s.value])], 
        [value = s.value;])[]b4_locations_if([ 
    location = s.location;])[ 
    } 

不幸的是,我無法辨認這幾乎足以讓出運動比如std ::矢量數據結構的效率,部分是由於我的無知m4語法。

在我的語法有鑑於此:

%define api.token.constructor 
%define api.value.type variant 
%type < std::vector<double> > numlist 
... 
numlist: 
    num    { $$ = std::vector<double>(); $$.push_back($1); } 
| numlist "," num { $$ = $1; $$.push_back($3); } 
; 

我不清楚對性能的影響。請注意,這將使用C++ 98編譯器而不是C++ 11編譯器進行編譯;因此不會有移動語義。

我在猜測$$ = std::vector<double>()聲明可能會被刪除;我認爲它已經是默認構建的,但我沒有測試過,我不確定野牛的內部變體類型是如何工作的。我特別感興趣的是$$ = $1; $$.push_back($3);是否會爲每個要添加的項目複製矢量?

我無法確定是否將此類型切換爲std::vector<double> *;誠然,使用野牛變種類型的原因大部分是使用普通的C++類型而不是指針聯合。


我也有一個解析器確實在事實上利用C++ 11/14和特別std::unique_ptr類似的好奇心。如果分配了一條左遞歸規則的行,如$$ = std::make_unique<...>(...),那麼以下操作可以執行$$ = $1; $$->...

回答

1

我顯然不是野牛/ Yacc的專家,但你可以看看生成的代碼:

 { 
    case 2: 
#line 20 "test.yy" // lalr1.cc:846 
    { yylhs.value.as< std::vector<double> >() = std::vector<double>(); 
     yylhs.value.as< std::vector<double> >().push_back(yystack_[0].value.as<double>()); } 
#line 1306 "test.tab.cc" // lalr1.cc:846 
    break; 

    case 3: 
#line 21 "test.yy" // lalr1.cc:846 
    { yylhs.value.as< std::vector<double> >() = yystack_[2].value.as< std::vector<double> >(); 
     yylhs.value.as< std::vector<double> >().push_back(yystack_[0].value.as<double>()); } 
#line 1312 "test.tab.cc" // lalr1.cc:846 
    break; 

parser::parse方法,在裏面有規定,並在那裏yylhsstack_symbol_type類型和yystack_的局部變量是一個屬性parser類別的類別stack_type(其中包含stack_symbol_type)。

它看起來像答案是,當你做$$ = $1時,整個向量將被複制,我看不到編譯器如何優化這個。的as聲明如下:

template <typename T> 
T& as(); 

隨着也const變種,所以做作是在類型T,而你的情況是std::vector<double>,從而一份拷貝完成。即使您已經使用c++11移動語義,也會進行復制,因爲RHS不是xvalue

+0

謝謝!我真的很想避免使用指針向量構造,但看起來這是最好的做法。 – Zac

+1

@Zac你認爲交換'$ 1'和'$$'而不是分配? –

+0

@邁克爾我沒有。你指的是std :: swap()? – Zac