У меня возникли проблемы с компиляцией заголовка класса, который содержит поле-член типа sregex.
Класс определяется как:
#include <boost/xpressive/xpressive_fwd.hpp>
namespace Bob
{
class RegexReplace
{
public :
boost::xpressive::sregex m_rx;
std::string m_str;
RegexReplace(const char* strSearch, const char* strReplace);
};
} // namespace Bob
Файл класса cpp компилируется без проблем, но когда я включаю заголовок в файл cpp, который использует класс, компилятор выдает следующую ошибку:
error: field ‘m_rx’ has incomplete type ‘boost::xpressive::sregex’ {aka ‘boost::xpressive::basic_regex<__gnu_cxx::__normal_iterator<const char*, std::__cxx11::basic_string<char> > >’}
boost::xpressive::sregex m_rx;
Что я здесь делаю не так???
Это действительно заголовок для предварительных объявлений, который, как я понял, должен был использоваться именно в этом случае - файл заголовка для включения в другие файлы. Предполагается, что это позволит избежать необходимости во всех других полных определениях. Или я что-то пропустил здесь?
Форвардные объявления предназначены для «эй, здесь есть тип, который я определю позже». Если вы хотите переслать объявление своего регулярного выражения, вам придется изменить его на указатель. Затем включите xpressive.hpp в файл cpp (чтобы определить его) и распределите динамически.
Я использую xpressive_static.hpp для статического, а не динамического регулярного выражения. Я бы с радостью создал sregex динамически (как указатель на статическое определение), но я не вижу, как это сделать — не так просто, как new sregex(...). Любой совет ?
Я бы придерживался стековой памяти, это быстрее, и код будет менее подвержен ошибкам.
По какой причине вы просто не удалите _fwd из заголовка и не назначите m_rx{sregex::compile(strSearch)} в списке инициализаторов?
Это означает, что я обязан включить xpressive_static.hpp, это разочаровывает. Я надеялся, что заголовок будет максимально легким.
Потому что я не использую sregex::compile — только статические определения
Пытаетесь сократить время компиляции? Для этого вы можете использовать предварительно скомпилированные заголовки (или перейти по маршруту указателя).





boost::xpressive::sregex m_rx; - это экземпляр, и вы только объявили его, включив ..._fwd.hpp, другими словами, он неполный.
#include <boost/xpressive/xpressive.hpp> должен решить проблему.
Если вы действительно хотите перенаправить объявление своего типа, вам придется изменить его на указатель (нерабочий код, похоже, что boost использует static::compile(...)):
хпп:
#include <boost/xpressive/xpressive_fwd.hpp>
namespace Bob
{
class RegexReplace
{
public :
boost::xpressive::sregex* m_rx;
std::string m_str;
RegexReplace(const char* strSearch, const char* strReplace);
~RegexReplace();
// @todo Implement move and copy semantics
};
} // namespace Bob
цена за тысячу показов:
#include <boost/xpressive/xpressive.hpp>
namespace Bob
{
RegexReplace::RegexReplace(const char* strSearch, const char* strReplace) :
m_rx{new boost::xpressive::sregex}
{
......
}
RegexReplace::~RegexReplace() {
delete m_rx;
}
}
Название
xpressive_fwd, вероятно, означает, что заголовок содержит только предварительные объявления. Таким образом, вы включаете неправильный заголовок, скорее всего.