Ошибка парсера SWIG

У меня есть следующий заголовочный файл.

#include <string>

namespace A {
namespace B {

    struct Msg {
        std::string id;
        std::string msg;

        Msg(std::string new_id, std::string new_msg)
        : id(new_id), msg(new_msg)
        {
        }
    };

    template<bool HAS_ID>
    class ID {
    public:
        template<typename TOBJ>
        auto get(TOBJ parent) -> decltype(parent.id()) {
            return parent.id();
        }
    };   
} // namespace B
} // namespace A

Когда я глотаю его, это дает мне ошибку

Error: Syntax error in input(3). в строке 20, указывающей на линию

auto get(TOBJ parent) -> decltype(parent.id())

Целевой язык - Java

Как я могу решить эту проблему? Я только хочу создать оболочку для Msg struct и ничего больше в заголовке. Поскольку это выглядит как ошибка парсера Swig, использование директивы% ignore, похоже, не работает.

Спасибо

1 ответ

Решение

Хотя SWIG 3.x добавлен ограниченным decltype Поддержка выглядит так, как будто ваш случай не поддерживается в настоящее время. (Увидеть decltype ограничения)

Я думаю, что лучшее, что вы получите на данный момент, - это окружить код, вызывающий проблемы, в макросах препроцессора, чтобы скрыть его, например:

#include <string>

namespace A {
namespace B {

    struct Msg {
        std::string id;
        std::string msg;

        Msg(std::string new_id, std::string new_msg)
        : id(new_id), msg(new_msg)
        {
        }
    };

    template<bool HAS_ID>
    class ID {
    public:
#ifndef SWIG
        template<typename TOBJ>
        auto get(TOBJ parent) -> decltype(parent.id()) {
            return parent.id();
        }
#endif
    };   
} // namespace B
} // namespace A

Если по какой-либо причине вы не можете отредактировать этот файл, есть два варианта:

  1. Не использовать %include с заголовочным файлом, который не анализируется. Вместо этого напишите что-то вроде:

    %{
    #include "header.h" // Not parsed by SWIG here though
    %}
    
    namespace A {
    namespace B {
    
        struct Msg {
            std::string id;
            std::string msg;
    
            Msg(std::string new_id, std::string new_msg)
            : id(new_id), msg(new_msg)
            {
            }
        };
    
    } // namespace B
    } // namespace A
    
    in your .i file, which simply tells SWIG about the type you want to wrap and glosses over the one that doesn't work.
    
  2. В качестве альтернативы проявите творческий подход к препроцессору и найдите способ скрыть его, используя бодж, внутри вашего файла.i вы можете написать что-то вроде:

    #define auto // \
    void ignore_me();
    
    %ignore ignore_me;
    

    Еще одна похожая ошибка - скрыть содержимое decltype с:

    #define decltype(x) void*
    

    Что просто говорит SWIG, что все типы использования decltype являются указателями на void. (Требуется SWIG 3.x и может быть объединен с%ignore, который должен выполнять игнорирование, или с картой типов, чтобы действительно исправить это)

Другие вопросы по тегам