#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 нет конструктора по умолчанию.
Вы должны предоставить параметры, поэтому просто обратитесь к документации.