2016-04-25 6 views
-1

Meine nullPointcheck Funktion:'va_start' in Funktion mit fester Parameterfehler

template<typename T, typename... Args> 
bool __nullPointCheck(T first, Args... args) 
{ 
    bool ret = true; 
    va_list vl; 
    auto n = sizeof...(args); 
    va_start(vl, n); 
    for (auto i = 0; i <= n; ++i) 
    { 
     auto p = va_arg(vl, T); 
     if (!p) 
     { 
      ret = false; 
     } 
    } 
    va_end(vl); 
    return ret; 
} 

aber ich bin immer NDK Build-Fehler wie folgt:

'va_start' used in function with fixed args 
va_start(vl, n); 

, wenn ich ändern, um die zweite param in va_start zuerst wie folgt:

va_start(vl, first); 

NDK-build-Export den Fehler wie folgt:

0.123.
 'va_start' used in function with fixed args 
    va_start(vl, first); 
    ^
E:/ANDROID_HOME/android-ndk-r10c/toolchains/llvm-3.5/prebuilt/windows-x86_64/bin 
\..\lib\clang\3.5\include\stdarg.h:33:29: note: 
expanded from macro 'va_start' 
#define va_start(ap, param) __builtin_va_start(ap, param) 

Es gibt keine Fehler in vs2013, aber der Code kann der NDK-build Bühne

+4

eine variadic Vorlage ist nicht das selbe, was die alte c vararg Liste Funktion. willst du sowas wie [this] (http://coliru.stacked-crooked.com/a/e69bba38673a8cd3)? –

+3

[OT]: '__nullPointCheck' ist ein reservierter Bezeichner –

+0

Durch Entfernen aller va_list verwandten Code, bekomme ich endlich meinen Code mit Hilfe von Parameter-Pack wie folgt übergeben: std :: array arr = {params ...} und iterieren das Array in einer Schleife. Aber ich habe viel von deiner Antwort gelernt. @ Piotr Skotnicki Vielen Dank! – rontgen

Antwort

3

va_start usw. können nur in einer Funktion verwendet werden, deren Prototyp in ...); endet. Dies unterscheidet sich von einem Parameterpaket. Ihr Code verwendet ein Parameterpaket. Die Syntax für die Verwendung von Parameterpaketen unterscheidet sich von der Syntax für variadische Funktionen.

Ich gehe davon aus, dass Ihre Funktion true nur dann zurückgeben sollte, wenn alle Argumente Nicht-Null-Zeiger sind. Ein Weg, um Ihre Funktion zu implementieren wäre:

inline constexpr bool nullPointCheck() { return true; } 

template<typename T, typename... Args> 
constexpr bool nullPointCheck(T&& first, Args&&... args) 
{ 
    return first && nullPointCheck(args...); 
} 

rontgens Antwort ist auch gut.


können Sie tatsächlich diese Funktion nutzen zu überprüfen, ob eine beliebige Argumentliste alle true ist. Ich habe universelle Referenzen verwendet, damit die Argumente nicht kopiert werden. dies macht keinen Unterschied für Zeiger, kann aber bei komplexeren Typen einen Unterschied machen.

Um die Funktion so zu beschränken, dass nur Zeiger akzeptiert werden, ändern Sie T&& in T *. (Lassen Sie Args&& wie es ist). Wenn Sie auch die wörtliche nullptr annehmen möchten, dann müssen Sie auch eine Überlastung:

inline constexpr bool nullPointCheck(std::nullptr_t) { return false; } 

weil nullptr eigentlich nicht an T * nicht ableiten.

1

Mein solusion geben, die das Stadium der Kompilation passieren kann, ist wie folgt:

template<typename T, typename... Params, std::size_t N = sizeof...(Params)> 
static bool nullPointCheck(Params... params) 
{ 
    std::array<T, N> arr = { params... }; 
    for (auto point : arr) 
    { 
     if (!point) 
     { 
      return false; 
     } 
    } 
    return true; 
} 
+1

Sie können auch 'false;' anstelle von 'ret = false' zurückgeben. Es macht auch keinen Sinn, dass eine Funktionsschablone "statisch" ist. –

+0

@ M.M. Danke für deinen Rat. Ich werde es reparieren. – rontgen

Verwandte Themen