提升精神Visual C ++编译器错误,GCC

时间:2015-12-08 20:13:56

标签: c++ csv boost boost-spirit boost-spirit-qi

我在使用Visual C ++(2015)进行编译时遇到以下 live demo code 时遇到问题。该代码在GCC中可以正常工作为 demonstrated here 。请有人帮我解决这个问题。我很擅长提升精神qi解析,并且在背景中使用所有模板魔法很难发现问题。我从堆栈溢出中的 here 中获得了CSV解析的初步灵感。

在Visual C ++下报告的编译器错误(通过在线在线编译器)如下:

Error(s):
source_file.cpp(103): error C2146: syntax error: missing ';' before identifier 'context_type'
source_file.cpp(140): note: see reference to class template instantiation 'CsvGrammar<It>::final' being compiled
source_file.cpp(147): note: see reference to class template instantiation 'CsvGrammar<It>' being compiled
source_file.cpp(103): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
source_file.cpp(146): error C2079: 'CsvGrammar<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>>::convert' uses undefined struct 'CsvGrammar<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>>::final'
source_file.cpp(158): note: see reference to class template instantiation 'CsvGrammar<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>>' being compiled

我桌面上的visual C ++ 2015下的错误如下所示:

1>------ Build started: Project: ConsoleApplication1, Configuration: Debug x64 ------
1>  Source.cpp
1>\\geihome1\home\jcoffey\visual studio 2015\projects\consoleapplication1\consoleapplication1\source.cpp(103): error C2146: syntax error: missing ';' before identifier 'context_type'
1>  \\geihome1\home\jcoffey\visual studio 2015\projects\consoleapplication1\consoleapplication1\source.cpp(140): note: see reference to class template instantiation 'CsvGrammar<It>::final' being compiled
1>  \\geihome1\home\jcoffey\visual studio 2015\projects\consoleapplication1\consoleapplication1\source.cpp(147): note: see reference to class template instantiation 'CsvGrammar<It>' being compiled
1>\\geihome1\home\jcoffey\visual studio 2015\projects\consoleapplication1\consoleapplication1\source.cpp(103): error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>\\geihome1\home\jcoffey\visual studio 2015\projects\consoleapplication1\consoleapplication1\source.cpp(146): error C2079: 'CsvGrammar<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>>::convert' uses undefined struct 'CsvGrammar<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>>::final'
1>  \\geihome1\home\jcoffey\visual studio 2015\projects\consoleapplication1\consoleapplication1\source.cpp(158): note: see reference to class template instantiation 'CsvGrammar<std::_String_const_iterator<std::_String_val<std::_Simple_types<char>>>>' being compiled
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

以下是有问题的代码(也复制到上面指出的现场演示网站)

#define BOOST_SPIRIT_USE_PHOENIX_V3
#include <iostream>
#include <boost/fusion/include/at_c.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>
#include <vector>

namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;

enum LineItems {
    SERVICENAME,
    POLYNOMIAL,
    MODULE,
    DLMUW,
    WSU,
    TCP,
    UDP,
    INAIR,
    CLIENTS,
//    RXPORTDCTRL,
//    TXPORTDCTRL,
//    RXPORTWCTRL,
//    TXPORTWCTRL,
//    RXPORTD1,
//    TXPORTD1,
//    RXPORTD2,
//    TXPORTD2,
//    RXPORTD3,
//    TXPORTD3,
//    RXPORTD4,
//    TXPORTD4,
//    RXPORTW1,
//    TXPORTW1,
//    RXPORTW2,
//    TXPORTW2
};

struct CsvLine {
    std::string ServiceName;
    std::string Polynomial;
    std::string Module;
    int DLMUW;
    int WSU;
    int TCP;
    int UDP;
    int InAir;
    int Clients;
//    std::string RxPortDCtrl;
//    std::string TxPortDCtrl;
//    std::string RxPortWCtrl;
//    std::string TxPortWCtrl;
//    int RxPortD1;
//    int TxPortD1;
//    int RxPortD2;
//    int TxPortD2;
//    int RxPortD3;
//    int TxPortD3;
//    int RxPortD4;
//    int TxPortD4;
//    int RxPortW1;
//    int TxPortW1;
//    int RxPortW2;
//    int TxPortW2;
};

using Column  = std::string;
using Columns = std::vector<Column>;
using CsvFile = std::vector<CsvLine>;

template<typename It>
struct CsvGrammar: qi::grammar<It, CsvFile(), qi::locals<std::vector<LineItems>>, qi::blank_type> {
    CsvGrammar() : CsvGrammar::base_type(start) {
        using namespace qi;
        static const char colsep = ',';

        item.add("ServiceName", SERVICENAME)("Polynomial", POLYNOMIAL)("Module", MODULE)("DLMUW", DLMUW)("WSU", WSU)("TCP", TCP)("UDP", UDP)("InAir", INAIR)("Clients", CLIENTS);
        start  = qi::omit[ header[_a=_1] ] >> eol >> line(_a) % eol;

        // Module was unused
        header = (item | omit[column] >> attr(MODULE)) % colsep;
        line   = (column % colsep) [convert];

        column = quoted | *~char_(",\n");
        quoted = '"' >> *("\"\"" | ~char_("\"\n")) >> '"';

        BOOST_SPIRIT_DEBUG_NODES((header)(column)(quoted));
    }

private:
    qi::rule<It, std::vector<LineItems>(),                      qi::blank_type> header;
    qi::rule<It, CsvFile(), qi::locals<std::vector<LineItems>>, qi::blank_type> start;
    qi::rule<It, CsvLine(std::vector<LineItems> const&),        qi::blank_type> line;

    qi::rule<It, Column(), qi::blank_type> column;
    qi::rule<It, std::string()> quoted;
    qi::rule<It, qi::blank_type> empty;

    qi::symbols<char, LineItems> item;

    struct final {
        using Ctx = typename decltype(line)::context_type;

        void operator()(Columns const& columns, Ctx &ctx, bool &pass) const {
            auto& csvLine   = boost::fusion::at_c<0>(ctx.attributes);
            auto& positions = boost::fusion::at_c<1>(ctx.attributes);
            int i =0;

            for (LineItems position : positions) {
                switch (position) {
                case SERVICENAME: 
                    csvLine.ServiceName = columns[i];              
                    break;
                case POLYNOMIAL:  
                    csvLine.Polynomial = columns[i]; 
                    break;
                case MODULE:  
                    csvLine.Module = columns[i]; 
                    break;
                case DLMUW:
                    csvLine.DLMUW = atoi(columns[i].c_str()); 
                    break;
                case WSU:
                    csvLine.WSU = atoi(columns[i].c_str()); 
                    break;
                case TCP:
                    csvLine.TCP = atoi(columns[i].c_str()); 
                    break;
                case UDP:
                    csvLine.UDP = atoi(columns[i].c_str()); 
                    break;
                case INAIR:
                    csvLine.InAir = atoi(columns[i].c_str()); 
                    break;
                case CLIENTS:
                    csvLine.Clients = atoi(columns[i].c_str()); 
                    break;
                default:   
                    break;
                }
                i++;
            }
            pass = true; // returning false fails the `line` rule
        }
    } convert;
};

int main() {
    const std::string s =
        "ServiceName,Polynomial,Module,DLMUW,WSU,TCP,UDP,InAir,Clients\n"
        "ALBF,0x82608EDB,nic1,1,0,1,1,1,6\n"
        "OmsMIS,0x04C11DB7,cmc,1,0,1,1,1,5\n"
        "FMS1,0x82F63B78,proc3,1,0,1,1,1,4\n"
        "FMS2,0x82F63B78,proc5,1,0,1,1,1,3";

    auto f(begin(s)), l(end(s));
    CsvGrammar<std::string::const_iterator> p;

    CsvFile parsed;
    bool ok = qi::phrase_parse(f, l, p, qi::blank, parsed);

    if (ok) {
        for (CsvLine line : parsed) {
            std::cout 
                << '[' << line.ServiceName << ']' 
                << '[' << line.Polynomial << ']' 
                << '[' << line.Module << ']' 
                << '[' << line.DLMUW << ']' 
                << '[' << line.WSU << ']'
                << '[' << line.TCP << ']'
                << '[' << line.UDP << ']'
                << '[' << line.InAir << ']'
                << '[' << line.Clients << ']';
            std::cout << std::endl;
        }
    } else {
        std::cout << "Parse failed\n";
    }

    if (f != l)
        std::cout << "Remaining unparsed: '" << std::string(f, l) << "'\n";
}

1 个答案:

答案 0 :(得分:4)

我很确定这是MSVC中的一个错误。由于某种原因,编译器在decltype上窒息(因为它是语法错误,很可能它们还没有实现它)。这是一个解决方法:

using workaround = decltype(line);
using Ctx = typename workaround::context_type;

This seems like the related bug report。它关闭为deferred ...... :(

相关问题