Hypercell ein ] Hypercell aus ] Zeige Navigation ] Verstecke Navigation ]
c++.de  
   

Die mobilen Seiten von c++.de:
http://m.c-plusplus.de
Infos hier [BETA]

  
c++.de :: C++ (auch C++0x und C++11) ::  sorry, unimplemented: mangling nontype_argument_pack     Zeige alle Beiträge auf einer Seite Auf Beitrag antworten
Autor Nachricht
314159265358979
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.03.2010
Beiträge: 4658
Beitrag 314159265358979 Mitglied 15:40:14 09.04.2012   Titel:   sorry, unimplemented: mangling nontype_argument_pack            Zitieren

Hallöle,

Sorry für den blöden Threadtitel, aber der Fehler ist so umfangreich, mir ist da nichts besseres eingefallen. Folgendes Szenario: Ich habe angefangen, Boost.Lambda nachzuprogrammieren, alle Operatoren sowie Platzhalter funktionieren bereits. Was mir Probleme bereitet, ist eine Art while Konstrukt.

Hier ein Beispiel, wie das ganze aussehen soll:
C++:
auto f = while_(_0)[--_0];

Diese Lambda nimmt also das erste Argument und dekrementiert es, bis es 0 ist.

Alle Ausdrücke werden vom CRTP Klassentemplate expression<DerivedType> abgeleitet. while_ ist eine Funktion, die einen solchen Ausdruck nimmt und eine while_expression<CondType> zurückgibt. Für while_expression ist der operator [] überladen, der eine while_body_expression<CondType, BodyType> zurückgibt.

while_body_expression sieht wie folgt aus:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
template <typename Cond, typename Body>
struct while_body_expression : expression<while_body_expression<Cond, Body>>
{
    while_body_expression(Cond cond, Body body)
        : cond(cond), body(body)
    {}
 
    template <typename... Args>
    void operator () (Args&&... args) const
    {
        while(cond(std::forward<Args>(args)...))
            body(std::forward<Args>(args)...);
    }
 
private:
    Cond cond;
    Body body;
};


Wenn ich die oben gegebene Lambda mit dem folgenden Stück Code instanziere und verwende:
C++:
auto f = while_(_0)[--_0];
int i = 20;
f(i);

, sagt mir der Compiler:
C++:
In file included from ../main.cpp:3:0:
../lambda/arithmetic_ops.hpp: In instantiation of 'decltype (-- declval<Expr>()((forward<Args>)(lambda::prefix_decrement_expression::operator()::args)...)) lambda::prefix_decrement_expression<Expr>::operator()(Args&& ...) const [with Args = {int&}; Expr = lambda::argument_placeholder_expression<0u>; decltype (-- declval<Expr>()((forward<Args>)(lambda::prefix_decrement_expression::operator()::args)...)) = int&]':
../lambda/while.hpp:21:5:   required from 'void lambda::while_body_expression<Cond, Body>::operator()(Args&& ...) const [with Args = {int&}; Cond = lambda::argument_placeholder_expression<0u>; Body = lambda::prefix_decrement_expression<lambda::argument_placeholder_expression<0u> >]'
../main.cpp:14:5:   required from here
../lambda/arithmetic_ops.hpp:22:2: sorry, unimplemented: mangling nontype_argument_pack

Wobei er in main.cpp auf die Zeile des Aufrufs verweist und in arithmetic_ops.hpp auf die Definition des operator --, die über folgende Makroinstanzierung
C++:
DEFINE_UNARY_EXPRESSION(prefix_decrement, --)

wie hier zu sehen aussieht:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#define DEFINE_UNARY_EXPRESSION_TYPE(name, op) \
    template <typename Expr> \
    struct name##_expression : expression<name##_expression<Expr>> \
    { \
        name##_expression(Expr expr) \
            : expr(expr) \
        {} \
    \
        template <typename... Args> \
        auto operator () (Args&&... args) const \
            -> decltype(op std::declval<Expr>()(std::forward<Args>(args)...)) \
        { \
            return op expr(std::forward<Args>(args)...); \
        } \
    \
    private: \
        Expr expr; \
    };

#define DEFINE_UNARY_EXPRESSION(name, op) \

    DEFINE_UNARY_EXPRESSION_TYPE(name, op) \
    \
    template <typename Derived> \
    name##_expression<Derived> expression<Derived>::operator op () const \
    { \
        return name##_expression<Derived>(derived_this()); \
    }

Dieses Makro definiert einen Typ prefix_decrement_expression und implementiert den in der Basisklasse expression<> deklarierten operator --.

Was mich wurmt, ist, dass die Operatoren alle ohne das while funktionieren. Erst wenn ich ein while in die Lambda einbaue kommen diese Fehler, völlig unabhängig davon, welche Operatoren ich nun in der Lambda verwende. Auch sehe ich nirgens ein "non-type argument pack".

Ich hoffe diese Fehlerbeschreibung ist irgendwie verständlich, ansonsten bitte einfach nachfragen.

Grüße,
PI
314159265358979
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.03.2010
Beiträge: 4658
Beitrag 314159265358979 Mitglied 10:28:39 11.04.2012   Titel:              Zitieren

Hat denn niemand eine Idee? :(
Tachyon
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.12.2003
Beiträge: 3467
Beitrag Tachyon Mitglied 12:54:31 11.04.2012   Titel:              Zitieren

sorry, unimplemented: mangling nontype_argument_pack ist normalerweise ein Hinweis darauf, dass der Compiler irgendetwas, dass unterstützt werden soll noch nicht kann.
Mit Deinem Code ist vermutlich alles i.O., nur kann der Compiler das in diesem speziellen Kontext noch nicht.

_________________
タキオン
314159265358979
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.03.2010
Beiträge: 4658
Beitrag 314159265358979 Mitglied 12:57:32 11.04.2012   Titel:              Zitieren

Ich weiß schon, dass der Hinweis das suggeriert. Aber ich hab doch nur argument packs mit Typen.
Tachyon
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.12.2003
Beiträge: 3467
Beitrag Tachyon Mitglied 13:12:37 11.04.2012   Titel:              Zitieren

314159265358979 schrieb:
Ich weiß schon, dass der Hinweis das suggeriert. Aber ich hab doch nur argument packs mit Typen.

Ich bin mir nicht sicher, wo das hier: lambda::argument_placeholder_expression<0u>; Body = lambda::prefix_decrement_expression<lambda::argument_placeholder_expression<0u> entsteht, aber da wird irgendwie ein Ganzahl-Argument eingesetzt. Ich tippe mal darauf, dass das Problem irgendwie darin liegt.

_________________
タキオン
314159265358979
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.03.2010
Beiträge: 4658
Beitrag 314159265358979 Mitglied 13:29:30 11.04.2012   Titel:              Zitieren

Das ist der Placeholder, das Placeholder Template sieht so aus:
C++:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
template <unsigned N>
struct argument_placeholder_expression : expression<argument_placeholder_expression<N>>
{
    template <typename Head, typename... Tail>
    auto operator () (Head&&, Tail&&... tail) const
        -> decltype(argument_placeholder_expression<N - 1>()(std::forward<Tail>(tail)...))
    {
        return argument_placeholder_expression<N - 1>()(std::forward<Tail>(tail)...);
    }
};
 
template <>
struct argument_placeholder_expression<0> : expression<argument_placeholder_expression<0>>
{
    template <typename Head, typename... Tail>
    Head operator () (Head&& head, Tail const&...) const
    {
        return head;
    }
};
 
argument_placeholder_expression<0> const _0;
argument_placeholder_expression<1> const _1;
argument_placeholder_expression<2> const _2;
argument_placeholder_expression<3> const _3;
argument_placeholder_expression<4> const _4;
argument_placeholder_expression<5> const _5;
argument_placeholder_expression<6> const _6;
argument_placeholder_expression<7> const _7;
argument_placeholder_expression<8> const _8;
argument_placeholder_expression<9> const _9;


Zuletzt bearbeitet von 314159265358979 am 13:31:45 11.04.2012, insgesamt 2-mal bearbeitet
314159265358979
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.03.2010
Beiträge: 4658
Beitrag 314159265358979 Mitglied 13:47:24 11.04.2012   Titel:              Zitieren

Ich habe jetzt mal versucht, das Placeholder-Template durch je einen eigenen Typen für jeden Placeholder zu ersetzen. Hat leider nichts geändert.
Tachyon
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.12.2003
Beiträge: 3467
Beitrag Tachyon Mitglied 16:59:29 11.04.2012   Titel:              Zitieren

Ich habe mal nach nontype_argument_pack gesucht, und bin dabei auf folgende Seite gestoßen: Seite.
Dort wird etwas weiter unten beschrieben, was sich hinter einem nontype_argument_pack verbirgt, und anscheinend sind das neben ordinalen Konstanten auch Funktionsargumente. Vielleicht hängt es irgendwie mit dem Forwarding zusammen.

_________________
タキオン


Zuletzt bearbeitet von Tachyon am 17:00:33 11.04.2012, insgesamt 1-mal bearbeitet
314159265358979
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.03.2010
Beiträge: 4658
Beitrag 314159265358979 Mitglied 18:50:43 11.04.2012   Titel:              Zitieren

Okay, das wäre möglich, aber ich kanns mir irgendwie nicht vorstellen, bzw verstehe es auch nicht. Denn das while ruft die Expressions auch nicht anders auf, als es die Operatoren und Placeholder tun, und ohne funktioniert es ja offensichtlich :(
Tachyon
Mitglied

Benutzerprofil
Anmeldungsdatum: 03.12.2003
Beiträge: 3467
Beitrag Tachyon Mitglied 19:02:11 11.04.2012   Titel:              Zitieren

Schreib' doch vielleicht mal die Compilerbauer an. Vielleicht ist das ein Bug.

_________________
タキオン
314159265358979
Mitglied

Benutzerprofil
Anmeldungsdatum: 09.03.2010
Beiträge: 4658
Beitrag 314159265358979 Mitglied 12:00:51 13.04.2012   Titel:              Zitieren

War wohl wirklich irgendwas unimplementiert, auch wenn ich nicht weiß, was. Hab nun nen GCC 4.8 und es läuft. :o)
c++.de :: C++ (auch C++0x und C++11) ::  sorry, unimplemented: mangling nontype_argument_pack   Auf Beitrag antworten

Zeige alle Beiträge auf einer Seite




Nächstes Thema anzeigen
Vorheriges Thema anzeigen
Sie können Beiträge in dieses Forum schreiben.
Sie können auf Beiträge in diesem Forum antworten.
Sie können Ihre Beiträge in diesem Forum nicht bearbeiten.
Sie können Ihre Beiträge in diesem Forum nicht löschen.
Sie können an Umfragen in diesem Forum nicht mitmachen.

Powered by phpBB © 2001, 2002 phpBB Group :: FI Theme

c++.de ist Teilnehmer des Partnerprogramms von Amazon Europe S.à.r.l. und Partner des Werbeprogramms, das zur Bereitstellung eines Mediums für Websites konzipiert wurde, mittels dessen durch die Platzierung von Werbeanzeigen und Links zu amazon.de Werbekostenerstattung verdient werden kann.

Die Vervielfältigung der auf den Seiten www.c-plusplus.de, www.c-plusplus.info und www.c-plusplus.net enthaltenen Informationen ohne eine schriftliche Genehmigung des Seitenbetreibers ist untersagt (vgl. §4 Urheberrechtsgesetz). Die Nutzung und Änderung der vorgestellten Strukturen und Verfahren in privaten und kommerziellen Softwareanwendungen ist ausdrücklich erlaubt, soweit keine Rechte Dritter verletzt werden. Der Seitenbetreiber übernimmt keine Gewähr für die Funktion einzelner Beiträge oder Programmfragmente, insbesondere übernimmt er keine Haftung für eventuelle aus dem Gebrauch entstehenden Folgeschäden.