Domanda

I have a Visual Studio 2013 C++11 project where I've defined a tree-like structure (where each element of an iterator is itself a container).

struct some_tree;

class some_tree_iterator 
    : public boost::iterator_facade<
        some_tree_iterator,
        some_tree,
        std::forward_iterator_tag,
        some_tree>
{
public:
    // ...

private:
    // error C2027: use of undefined type 'some_tree'
    some_tree dereference() const { return some_tree( /*init values*/ ); };

    // ...
};

struct some_tree
{
    some_tree_iterator begin();
    some_tree_iterator end();
    std::string value() const;
};

int main(int argc, char* argv[])
{
    some_tree foo;
    for (auto x : foo)
    {
        std::cout << x.name() << std::endl;
        for (auto y : x)
        {
            std::cout << "\t" << y.value() << std::endl;
        }
    }

    return 0;
}

Is the only way around this use of undefined type problem to return a pointer to a new some_tree container? like this:

std::shared_ptr<some_tree> some_tree_iterator::dereference() const 
{ 
    return std::make_shared<some_tree>( /* init values*/ ); 
};
È stato utile?

Soluzione 2

In cases when you need several classes that use each other as complete type, you can use something like this:

class TestClass1;
class TestClass2;


class TestClass1
{
    int val;
    TestClass2 foo();
};
class TestClass2
{
    int val;
    TestClass1 foo();
};


TestClass2 TestClass1::foo()
{
    /* ... */
}
TestClass1 TestClass2::foo()
{
    /* ... */
}

Altri suggerimenti

Two methods:

Method 1

You must not reference the class until it is defined. So you must do:

struct some_tree;

class some_tree_iterator 
{
public:
    // ...

private:
    some_tree dereference() const;

    // ...
};

struct some_tree
{
    some_tree_iterator begin();
    some_tree_iterator end();
    std::string value() const;
};

some_tree some_tree_iterator::dereference() const { return some_tree( /*init values*/ ); };

STL Method:

Also, you may do like STL and define the iterator inside the struct some_tree (in fact, STL's iterators are templates so they are defined in the class, even if declared elsewhere):

struct some_tree
{
  class iterator 
    : public boost::iterator_facade<
        iterator,
        some_tree,
        std::forward_iterator_tag,
        some_tree>
  {
    public:

    private:
      some_tree dereference() const { return some_tree( /*init values*/ ); };

  };

  iterator begin();
  iterator end();
  std::string value() const;
};
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top