Using undefined type
<pre><code>//file list.h
#include "stdafx.h"

namespace st
{
    struct My_List;
    typedef My_List list;
    list* create(const char* name);
}

//file list.cpp
#include "stdafx.h"
#include "list.h"
namespace st
{
    struct My_List
    {
        const char* name_;
        My_List* left_;
        My_List* right_;

        My_List(const char* name):name_(name),
            left_(nullptr),
            right_(nullptr)
        {}
        My_List(const My_List&amp;);

        ~My_List()
        {

        }
        void insert(My_List*);

        void set_name(char* name)
        {

            name_ = name;
        }

        const char* get_name()const
        {
            return name_;
        }
    };
    typedef My_List list;

    /*helper class for optor+ */
    struct MyChar
    {
        const char* my_data_;
        MyChar(const char* c_string):my_data_(c_string){}
        operator const char*()
        {
            return my_data_;
        }
        operator char*()
        {
            return const_cast&lt;char*&gt;(my_data_);
        }

    };

    char* operator+(MyChar left_, MyChar right_)
    {
        if (!left_.my_data_ || !right_.my_data_)
        {
            return 0;
        }
        size_t size = 1;//size is set to one for final '\0' char in an array
        char* p = "";//if both c_strings are empty this is returned
        bool has_left_ = false;
        bool has_right_ = false;
        if (strlen(left_))
        {
            size += strlen(left_);
            has_left_ = true;
        }
        if (strlen(right_))
        {
            size += strlen(right_);
            has_right_ = true;
        }
        bool both = has_left_ &amp;&amp; has_right_ ? true : false;
        if (both)
        {
            p = new char[size]();
            const void* p_v = p;//just to keep address of beginning of p
            const char* tmp = left_;
            /*copying first c_string*/
            while (*p++ = *tmp++);

            tmp = right_;
            /*one too far after last loop*/
            --p;
            while (*p++ = *tmp++);

            *p = '\0';
            /*go back to the beginning of an array*/
            p = static_cast&lt;char*&gt;(const_cast&lt;void*&gt;(p_v));
            return p;
        }
        else if (has_left_)
        {
            return left_;
        }
        else if (has_right_)
        {
            return right_;
        }
        return p;//returns "" if both c_strings were empty
    }


    My_List::My_List(const My_List&amp; pat):left_(nullptr),right_(nullptr)
    {
        name_ = pat.name_ + MyChar("_cpy");
        My_List* pattern = const_cast&lt;My_List*&gt;(&amp;pat);
        My_List* target = this;
        while (pattern-&gt;right_)
        {

            target-&gt;right_ = static_cast&lt;My_List*&gt;(malloc(sizeof(My_List)));
            *target-&gt;right_ = *pattern-&gt;right_;
            target-&gt;right_-&gt;set_name(pattern-&gt;right_-&gt;get_name() + MyChar("_cpy"));
            target-&gt;right_-&gt;left_ = static_cast&lt;My_List*&gt;(malloc(sizeof(My_List)));
            *target-&gt;right_-&gt;left_ = *pattern-&gt;right_-&gt;left_;
            target-&gt;right_-&gt;left_-&gt;set_name(pattern-&gt;right_-&gt;left_-&gt;get_name() + MyChar("_cpy"));
            pattern = pattern-&gt;right_;
            target = target-&gt;right_;
        }
    }

    void My_List::insert(My_List* obj)
    {
        /*to catch first branch*/
        My_List* tmp = this;
        if (tmp-&gt;right_)
        {
            /*go to the end of right side*/
            while (tmp-&gt;right_)
            {
                tmp = tmp-&gt;right_;
            }

            tmp-&gt;right_ = obj;
            obj-&gt;left_ = tmp;
        }
        else
        {
            tmp-&gt;right_ = obj;
            obj-&gt;left_= this;
        }
    }
    My_List* create(const char* name)
    {
        return new My_List(name);
    }
}

//file main.cpp
#include "stdafx.h"
#include "list.h"
using namespace st;

int _tmain(int argc, _TCHAR* argv[])
{

    list* my = create("a");
    list* b = create("b");
    my-&gt;insert(b);//HERE I'M GETTING ERROR
    return 0;
}
</code></pre>

<p>err msg:
'Error 1 error C2027: use of undefined type 'st::My_List' 13'</p>

<p>Why? Especially that if I comment this line it will get compiled and create() is using this type.</p>
