【问题标题】:use of undefined type error defining a tree使用未定义类型错误定义树
【发布时间】:2014-04-17 19:50:35
【问题描述】:

我有一个 Visual Studio 2013 C++11 项目,我在其中定义了一个树状结构(其中迭代器的每个元素本身就是一个容器)。

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;
}

解决这个use of undefined type 问题的唯一方法是返回指向新some_tree 容器的指针吗?像这样:

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

【问题讨论】:

  • 您能分享一下您的完整编译器错误吗?
  • @PaulDraper:它位于它引用的行上方代码的注释中。

标签: c++ c++11 containers


【解决方案1】:

两种方法:

方法一

在定义之前,您不得引用该类。所以你必须这样做:

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 方法:

另外,你也可以像 STL 一样在 struct some_tree 中定义迭代器(事实上,STL 的迭代器是模板,所以它们是在类中定义的,即使在其他地方声明):

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;
};

【讨论】:

  • 这不会解决问题,因为当编译器到达begin 的声明时,some_tree_iterator 将是未定义的。 (基本上相同的问题,但反过来。)
  • 实际上,只有在 beginend 函数被内联定义时才会发生这种情况。
  • 但确实感谢您指出这一点。与其改变类的顺序,不如不要内联定义函数。
【解决方案2】:

如果你需要几个类相互使用作为完整类型,你可以使用这样的东西:

class TestClass1;
class TestClass2;


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


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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-07
    相关资源
    最近更新 更多