forward typedef ohne typedef in C++Next



  • folgende Situation:

    // Datei Foo.h
    #include "FatClass.h" // eine Klasse mit vielen Abhängigkeiten
    class Foo {
        int idx;
        FatClass fat;
    };
    

    dann geht in einem anderen H-File:

    // Datei egal.h
    class Foo; // forward Foo - reicht hier!
    class Egal {
    public:
        void macheWas( Foo& foo );
    };
    

    Jetzt möchte ich mir in Foo.h die class sparen und schreibe z.B.:

    // Datei Foo.h
    #include "FatClass.h" // eine Klasse mit vielen Abhängigkeiten
    #include <utility> // std::tuple
    typedef std::tuple< int, FatClass > Foo;
    

    .. und prompt kompilert der Code nicht mehr, da Foo keine Klasse ist und irgendwo bekommt man dann einen 'redefined' Error.

    Ich kennen diesen Thread zum Thema 'Forward declaration of a typedef' und weiß auch, dass man ein FooForward.h bauen kann:

    // Datei FooForward.h
    class FatClass;
    #include <utility> // std::tuple
    typedef std::tuple< int, FatClass > Foo;
    

    nur würde mich interessieren, warum C++ als Sprache eine forward declaration von typedef nicht zulässt und ob das jemals Thema bei C++11 oder vielleicht C++14 war oder ist.
    Ich könnte mir vorstellen, dass man z.B. mit

    typename Foo; // Foo ist class, struct oder typedef
    

    den Compiler ausreichend informiert.

    Gruß
    Werner



  • Tuts doch:

    template <typename FatClass>
    using Foo = std::tuple<int, FatClass>;
    


  • ScottZhang schrieb:

    Tuts doch:

    template <typename FatClass>
    using Foo = std::tuple<int, FatClass>;
    

    na ja - ob ich jetzt typedef (s.o.) oder using hinschreibe ist Jacke wie Hose. Die Frage ist, warum ich nicht auch auf das std::tuple<..> verzichten kann.



  • Werner Salomon schrieb:

    ... nur würde mich interessieren, warum C++ als Sprache eine forward declaration von typedef nicht zulässt und ob das jemals Thema bei C++11 oder vielleicht C++14 war oder ist.
    Ich könnte mir vorstellen, dass man z.B. mit

    typename Foo; // Foo ist class, struct oder typedef
    

    den Compiler ausreichend informiert

    Ein typedef stellt im Gegensatz zu class/struct keinen eigenständigen Typ dar und es gäbe Probleme mit eindeutigen Funktions-Signaturen:

    typedef int foo_t;
    
    void foo(foo_t);  // Signatur: void foo(int)
    
    class foo_t;
    
    void foo(foo_t);  // Signatur: void foo(foo_t)
    
    typename foo_t;
    
    void foo(foo_t);  // Signatur: void foo(???)
    


  • Werner Salomon schrieb:

    ScottZhang schrieb:

    Tuts doch:

    template <typename FatClass>
    using Foo = std::tuple<int, FatClass>;
    

    na ja - ob ich jetzt typedef (s.o.) oder using hinschreibe ist Jacke wie Hose.

    Naja, mit dem typedef kriegste eben kein Alias hin.

    Werner Salomon schrieb:

    Die Frage ist, warum ich nicht auch auf das std::tuple<..> verzichten kann.

    Nee, also die Frage kann ich in deinem Original post nicht finden, sry.

    Was du sucht ist in wirklich ein Template und das gibs schon.

    typename foo;
    
    class A
    {
      foo bar;
    };
    

    VS

    template <typeanme foo>
    class A
    {
      foo bar;
    };
    

    See?



  • Hallo osdt,

    interessanter Hinweis.
    Es ist aber nicht möglich ein typedef mit einem Typnamen zu definieren bzw. umgekehrt. Jedoch der umgekehrte Fall könte zutreffen - nämlich unterschiedliche Namen für gleiche Typen:

    typename Foo; // Foo ist ein Typ
    void func( Foo& );
    void func( int& );
    

    wäre zunächst ok, aber in einer anderen Übersetzungseinheit steht dann vielleicht:

    typedef int Foo;
    

    was dann zu zwei implementierungen ein und derselben Funktion führt.

    .. das könnte der Grund sein.

    Gruß
    Werner



  • Hallo ScottZhang,

    ScottZhang schrieb:

    Werner Salomon schrieb:

    Die Frage ist, warum ich nicht auch auf das std::tuple<..> verzichten kann.

    Nee, also die Frage kann ich in deinem Original post nicht finden, sry.

    Werner Salomon schrieb:

    nur würde mich interessieren, warum C++ als Sprache eine forward declaration von typedef nicht zulässt und ob das jemals Thema bei C++11 oder vielleicht C++14 war oder ist.
    Ich könnte mir vorstellen, dass man z.B. mit

    typename Foo; // Foo ist class, struct oder typedef
    

    den Compiler ausreichend informiert.

    .. und was ich meinte war: wieso ich nicht einfach sagen kann, dass Foo irgendein Typ ist. Also ich möchte da kein std::tuple noch ein std::pair noch sonst was in der forward-declaration sehen.

    ScottZhang schrieb:

    See?

    Nö - ich habe Sonnenbrillen auf 🕶 und es ist Winter.

    wie sieht denn Deiner Meinung nach die H-Datei 'egal.h' (s.o.) dann aus? Bedenke, dass sich die Implementierung der Methode

    void macheWas( Foo& foo );
    

    in einer anderen Datei (egal.cpp) befindet?

    Gruß
    Werner



  • Der Grund ist, dass ein typedef keinen eigenständigen Typ darstellt und sich somit (auch bei einer Forward-Deklaration) von class/struct unterscheidet:

    typedef int foo_t:
    
    struct bar {
        void foo(int);
        void foo(foo_t);  // error
    };
    
    class foo_t;
    
    struct bar {
        void foo(int);
        void foo(foo_t);  // ok, foo_t ist ein eigenständiger Typ
    };
    


  • Danke osdt,

    ich denke das ist es.



  • Werner Salomon schrieb:

    [...]
    und was ich meinte war: wieso ich nicht einfach sagen kann, dass Foo irgendein Typ ist. Also ich möchte da kein std::tuple noch ein std::pair noch sonst was in der forward-declaration sehen.

    Ah verstehe, aber wie gesagt; das ist ja möglich aber nicht als forward Dekl sondern dann eben gänzlich über Templates.

    wie sieht denn Deiner Meinung nach die H-Datei 'egal.h' (s.o.) dann aus? Bedenke, dass sich die Implementierung der Methode

    void macheWas( Foo& foo );
    

    in einer anderen Datei (egal.cpp) befindet?

    Das geht nicht.


Log in to reply