2016-06-13 6 views
3

Ich mache C/C++ - Programmierung (meistens C++) und ich bin in der Notwendigkeit, Code zu faktorisieren, der wirklich doppelt so ist, außer jedes Vorkommen von "links" wird ersetzt durch " Recht". Sobald der Code fertig ist, muss ich wissen, ob es die "linke" oder "rechte" Version ist, die ausgeführt wird, aber das ist alles, beide werden eine Zahl zurückgeben, aus der ich Sinn machen kann (einmal kombiniert mit der linken oder rechten Information) .C++: Factorize-Code ohne eine Million Argumente zu übergeben

In diesem Setup muss jede Änderung zweimal durchgeführt werden, und das ist ärgerlich.

So könnte ich einfach faktorisieren, indem Sie links/rechts durch "andere" ersetzen und die faktorisierte Funktion zweimal aufrufen, jedes Mal wissend, wenn ich es für "links" oder für "rechts" nenne.

Jetzt, da wir diesen Teil des Codes erreichen, gibt es bereits eine Million Variablen (Cursor, IDs, Arrays gefüllt, etc ...). Wenn ich also den Links-/Rechts-Code faktorisieren wollte, würde ich die Funktion brauchen, um eine Unmenge von Argumenten zu haben, und das würde ziemlich hässlich aussehen.

Ich möchte auch nicht meine C++ - Klasse mit Attributen überladen, die nur in diesem Fall verwendet werden.

Irgendwelche Vorschläge, um hier reibungslos zu faktorisieren?

int arrayRight[many], arrayLeft[many], cursor; 

    while(1) 
    { 
     rightThing = arrayRight[cursor]; 
     // Process with RightThing assigned 
     // ... 
     // ... 
     // ... 

     leftThing = arrayLeft[cursor] 
     // Process with RightThing assigned 
     // ... 
     // ... 
     // ... 

     cursor++; 
    } 
+0

Sie können Gruppe Ihre Argumente in struct/class und dann nur jene Instanz übergeben. – Jarod42

+0

Dachte darüber nach, aber immer noch ein Streit um eine Struktur nur für diese einmal zu definieren –

Antwort

4

Versuchen Sie das? (Es funktioniert nur auf C 14 ++, da es automatisch Lambda verwendet)

auto func = [&](auto& theThing){ 
    // blah, blah code 
}; 

func(arrayRight[cursor]); 
func(arrayLeft [cursor]); 

[&] hier bedeutet Import alle Variablen im gleichen Umfang in die Lambda-Funktion.

Für ältere C++ - Version verwende ich den folgenden Code als hässlich (in einem Schulprojekt von C99).

int* pData[2] = {arrayRight, arrayLeft}; 
for (int i=0; i<2; i++) 
{ 
    int* theThing = pData[i]; 
    // blah, blah 
} 

Einige meiner Freunde sagten mir Makro kann VA_ARGS halten, also hier ist ein Makro-Weg. Es sollte am GCC funktionieren. Aber für MSVC 2003 funktioniert es nicht. (__typeof müssen durch boost::typeof ersetzt werden, und anonyme struct-Definition wird in älteren Version von MSVC nicht unterstützt)

#define in(...) __VA_ARGS__ 
#define PP_ARG_N(\ 
      _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, _32, _33, _34, _35, _36, _37, _38, _39, _40, \ 
     _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \ 
     _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, \ 
     _61, _62, _63, N, ...) N 
#define PP_RSEQ_N()          \ 
     63, 62, 61, 60,         \ 
     59, 58, 57, 56, 55, 54, 53, 52, 51, 50,   \ 
     49, 48, 47, 46, 45, 44, 43, 42, 41, 40,   \ 
     39, 38, 37, 36, 35, 34, 33, 32, 31, 30,   \ 
     29, 28, 27, 26, 25, 24, 23, 22, 21, 20,   \ 
     19, 18, 17, 16, 15, 14, 13, 12, 11, 10,   \ 
      9, 8, 7, 6, 5, 4, 3, 2, 1, 0 
#define PP_NARG_(...) PP_ARG_N(__VA_ARGS__) 
#define PP_NARG(...)  PP_NARG_(__VA_ARGS__, PP_RSEQ_N()) 

#define withInternal(dataType, desiredType, x, dataCnt, data...) for(struct {size_t __i; dataType __t[dataCnt];} __s = {0, data}; x = __s.__t[__s.__i], __s.__i < dataCnt; __s.__i++) 
#define with(x, ...) withInternal(__typeof(__VA_ARGS__), __typeof(__VA_ARGS__), x, PP_NARG(__VA_ARGS__), __VA_ARGS__) 
#define withConst(x, ...) withInternal(__typeof(__VA_ARGS__), __typeof((__VA_ARGS__) + 0), x, PP_NARG(__VA_ARGS__), __VA_ARGS__) 
#define withType(tn, x, ...) withInternal(tn, tn, x, PP_NARG(__VA_ARGS__), __VA_ARGS__) 

und wenn Sie es verwenden:

int main() 
{ 
    int x; 
    int s1=2, s2=3; 
    with(x, in(s1, s2)) 
     cout<<x<<endl; 
    withConst(x, in(45, 55)) 
     cout<<x<<endl; 
    withType(int, x, in(45, s1, 55, s2)) 
     cout<<x<<endl; 
    return 0; 
} 

Ich glaube, es ist klar.

  • with Arbeiten mit Variablen (im Grunde), weil, wenn consts zu with, gcc vorbei __typeof einen automatisierten const Typen für x erzeugen, die nicht zugeordnet werden können.
  • withConst verwendet einen x+0 Trick, um den Const-Typ der Variablen zu entfernen, aber + Operator funktioniert nicht bei jedem Datentyp, so dass es Einschränkungen hat.
  • withType gibt einen Datentyp an, der für eine gemischte Situation geeignet ist.
+1

Sieht aus wie 'ArrayRight' und' ArrayLeft' sind 'int' Arrays, so könnten Sie einfach' int & 'verwenden, damit es in C++ 11 funktioniert . – TartanLlama

+0

Wir diskutieren gerade über den Wechsel zu C++ 2003, also kein C++ 14 bis irgendwann! Aber ich mag die Idee. –

+0

@TartanLlama Noch müssen diese Zeiger übergeben ... Es gibt ein paar mehr Arrays als ich hier beschrieben ... –

0

Ich glaube, Sie batching Dinge zusammen, wie diese könnten versuchen:

while(1) 
{ 
    vector<int> things; 

    int rightThing = arrayRight[cursor]; 
    things.push_back(rightThing); 

    int leftThing = arrayLeft[cursor]; 
    things.push_back(leftThing); 

    for(vector<int>::iterator thing = things.begin(); thing != things.end(); ++thing) 
    { 
     // Process Thing 
     // ... 
     // ... 
     // ... 
    } 

    cursor++; 
} 
Verwandte Themen