| Autor |
Nachricht |
314159265358979
Mitglied
Benutzerprofil
Anmeldungsdatum: 09.03.2010
Beiträge: 4658
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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. |
|
|
|
 |
|
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.
|
|
|
|
|