Могу ли я обернуть boost graph своим собственным классом

#c #boost-graph

#c #boost-graph

Вопрос:

Я пытаюсь создать свой собственный класс с помощью boost::adjacency_matrix graph в качестве члена, но я застрял на ошибке компиляции. Пример класса, который не будет компилироваться:

 namespace zto {

typedef boost::adjacency_matrix<boost::undirectedS> Graph;

class SampleClass
{
public:
    Graph g;
    SampleClass();
};
  

И ошибка компиляции:

 ./src/sample.cpp: In constructor ‘zto::SampleClass::SampleClass()’:
./src/sample.cpp:27:31: error: no matching function for call to 
  ‘boost::adjacency_matrix<boost::undirectedS>::adjacency_matrix()’
./src/sample.cpp:27:31: note: candidates are:
/usr/include/boost/graph/adjacency_matrix.hpp:622:5: note: template<class EdgeIterator, 
  class EdgePropertyIterator> boost::adjacency_matrix::adjacency_matrix(EdgeIterator, 
  EdgeIterator, EdgePropertyIterator, boost::adjacency_matrix<Directed, VertexProperty, 
  EdgeProperty, GraphProperty, Allocator>::vertices_size_type, const GraphPropertyamp;)
/usr/include/boost/graph/adjacency_matrix.hpp:604:5: note: template<class EdgeIterator> 
  boost::adjacency_matrix::adjacency_matrix(EdgeIterator, EdgeIterator, 
  boost::adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, 
  Allocator>::vertices_size_type, const GraphPropertyamp;)
/usr/include/boost/graph/adjacency_matrix.hpp:593:5: note: 
  boost::adjacency_matrix<Directed, VertexProperty, EdgeProperty, GraphProperty, 
  Allocator>::adjacency_matrix(boost::adjacency_matrix<Directed, VertexProperty, 
  EdgeProperty, GraphProperty, Allocator>::vertices_size_type, const GraphPropertyamp;) 
  [with Directed = boost::undirectedS, VertexProperty = boost::no_property, EdgeProperty 
  = boost::no_property, GraphProperty = boost::no_property, Allocator = 
  std::allocator<bool>, boost::adjacency_matrix<Directed, VertexProperty, EdgeProperty, 
  GraphProperty, Allocator>::vertices_size_type = unsigned int]
/usr/include/boost/graph/adjacency_matrix.hpp:593:5: note:   candidate expects 2 
  arguments, 0 provided
/usr/include/boost/graph/adjacency_matrix.hpp:474:9: note: 
  boost::adjacency_matrix<boost::undirectedS>::adjacency_matrix(const 
  boost::adjacency_matrix<boost::undirectedS>amp;)
/usr/include/boost/graph/adjacency_matrix.hpp:474:9: note:   candidate expects 1 
  argument, 0 provided
  

Похоже, что компилятор считает Graph функцией ?!

Может кто-нибудь сказать мне, как объявить boost::adjacency_matrix в качестве члена моего класса?

Ответ №1:

Объект-член вашего класса инициализируется с использованием конструктора по умолчанию, если вы не укажете что-либо еще в качестве инициализатора. Похоже, что у adjacency_matrix нет конструктора по умолчанию.

Вместо этого вы должны сделать что-то вроде этого:

typedef boost::график смежности;

 class SampleClass
{
public:
    Graph g;
    SampleClass(size_t arg)
    : g(arg) // this is important
    {
      // As before, can also be in a cpp. 
      // It is just important that the initializer is used.
    }

};
  

Конечно, на практике вы также можете использовать другие аргументы конструктора, использовать выигранные значения по умолчанию и т. Д. Это должен быть просто очень простой пример. Я никогда не использовал boost::adjecency_matrix, поэтому я не знаю о хорошей практике и о том, что на самом деле имеет смысл. Я просто взял это из сообщения об ошибке.

Ответ №2:

Компилятор сообщает вам, что boost::adjacency_matrix не имеет конструктора, не принимающего аргументов, поэтому он не может создать его в качестве члена вашего класса. Объектные члены классов должны создаваться одновременно с созданием содержащего класса, и если вы не укажете иное, компилятор предполагает, что существует конструктор без параметров, которые он может вызывать. Когда этого нет, вы получаете подобные ошибки.

Решение состоит в том, чтобы предоставить параметры для конструктора g в списке инициализаторов вашего конструктора:

 SampleClass() : g( ... )
{
}
  

Где … являются ли соответствующие параметры конструктора для любого из конструкторов adjacency_matrix, который дает вам нужный объект. Это переопределит инстинкт компилятора по умолчанию, чтобы попытаться вызвать конструктор с 0 параметрами и заставить его вызывать тот, который соответствует параметрам, которые вы предоставляете вместо этого.

Если вы не хотите делать это во время построения вашего класса, вам придется сохранить указатель на него и создать его с помощью new в соответствующее время. Или, что еще лучше, сохраните в нем shared_ptr, чтобы вам не приходилось беспокоиться о его удалении при уничтожении вашего класса.

Ответ №3:

Насколько я понимаю, для Graph нет конструктора по умолчанию.

Вы должны предоставить параметры, поэтому просто обратитесь к документации.