2016-05-13 51 views
0

我想在YACC文件中添加結構工會,但我發現這個錯誤:結構工會C++ YACC

"error : member 'Info YYSTYPE ::info' with constructor not allowed in union "

%{ 
#include <cstdio> 
#include <iostream> 
using namespace std; 

extern "C" int yylex();       
extern "C" int yyparse();    
extern "C" FILE *yyin;     
struct Info{ int intval; float floatval; string stringval ;int type; } 

void yyerror(const char *s); 
%} 

%union { 

int ival; 
float fval; 
char *sval; 

struct Info info; 

} 
+0

錯誤告訴你幾乎到底是什麼問題:C++不允許你在聯合中使用一個構造函數(非POD類型)。沒有什麼特別與yacc有關。 –

+0

[...與構造函數不允許在聯合問題中可能重複](http://stackoverflow.com/questions/6014717/with-constructor-not-allowed-in-union-problem) – Schore

回答

1

你不能把非POD結構的工會在C++中,因爲編譯器無法告訴哪個聯合成員構建或破壞。

一種替代方法是在聯合使用指針:

在這種情況下
%union { 
    ... 
    Info *info; 
}; 

你必須要小心明確刪除指針,如果/當他們不再需要。如果出現錯誤,野牛的%destructor在這裏可以用來避免泄漏。

或者,不使用%union在所有 - 只是定義YYSTYPE作爲一個單一的類型:

%{ 
#define YYSTYPE struct Info 
%} 

在這種情況下,所有的規則需要使用相同類型的(沒有%type聲明有不同的規則產生不同的東西)。類似boost::variant可以是有用的,如果你真的需要有不同的類型..

0

我看不到同時使用同一個成員的聯合和結構的觀點。你應該使用一個或另一個。

如果您告訴野牛發出C++解析器,您可以選擇使用類似變體的語義類型。無論是C還是C++解析器,都可以使用聯合或結構,但在任何情況下,您都可以將C++ std::string作爲聯合成員,甚至間接地包含該錯誤消息中指出的原因。這與野牛很少有關係;除非聯合本身具有構造函數,否則C++不會讓你定義具有構造函數的成員的聯合。 (如果你試圖編寫所需的構造函數,你可能會明白爲什麼語言沒有辦法爲你做。)

如果你不想亂用內存管理,野牛的變種選項可能是爲你。閱讀手冊中的文檔。否則,可以使用指向std::string(使用new運算符創建)的指針,也可以只使用C字符串。在這兩種情況下,您都需要分配和釋放存儲空間。

0

聯盟只允許您使用原始類型和指針。

如果您需要使用結構,那麼在聯合中,您只能聲明指向該結構的指針。