2012-08-09 74 views
-1

是否有一種非增強方式來創建一個帶有可變參數的函數?我知道參數類型參數個數它們是通常是小於5,所有相同類型變量參數

我需要知道是否有一種方法,而不提供參數計數或用空結束參數列表。

+3

用google搜索「variadic arguments C++」。 – 2012-08-09 06:22:02

+0

-1問題措詞與預期問題有關。 – 2012-08-09 07:25:08

+1

這是爲什麼標記C?兩者的答案會非常不同。在C中,你可以用宏來實現,但是你的反升壓聲明似乎表明你不會喜歡它。 – 2012-08-09 07:59:43

回答

1

對於最多5個參數都是相同的類型,簡單的重載可以做到這一點。

更爲通用,支持任意數量的相同類型的參數,只需傳遞一個集合,如std::vector

對於在每次調用中動態構建這種集合的C++ 03技術,請參閱my other answer;對於C++ 11,如果您不需要支持Visual C++,則可以使用大括號初始值設定項列表作爲實際參數。

3

我知道參數類型,他們通常小於5

如果不會大於5,然後簡單的過載可以做的工作。調用接受來自所有其他接受少於5個參數的重載參數的maximam數量的重載,或者定義一個worker(內部)函數,從重載中調用它。

如果可能的話,您可以使用某些參數的默認值,如果這有助於減少重載函數的數量。

在C++ 11中,您可以使用variadic-template

+0

我不明白爲什麼要使用可變參數模板,如果參數類型是已知的,並且顯然是固定的? – 2012-08-09 06:40:34

+1

@JakobS。如果真正的最大數量的參數是未知的(OP表示*通常*小於5),並且C++ 11可變參數模板是一種可能性,那麼我會說C++ 11可變參數模板顯然是手動的,最好的解決方案。 – 2012-08-09 07:04:46

+0

考慮重載支持3個參數。有5種可能的參數類型,你需要5^3 = 125個重載,加上25個重載的兩個參數,5個重載的1個參數和單個無參數的版本;一般來說,對於**(5 ^(n + 1)-1)/ 4重載**的n個參數。這對我的口味有點太過分了。 – 2012-08-09 07:07:56

0

cstdarg你在找什麼?這是用標準的C++方法來生成具有可變數量參數的函數。

+0

不確定這是否是標準方式,當然是一種方式。在C++中有嚴重的限制,因爲對象不能以這種方式傳遞。 – jahhaj 2012-08-09 06:45:57

0

您應該能夠使用va_list實現傳遞可變參數。

0

作爲一般的C++ 03解決方案,您可以提供一個setter,它返回對其所調用的對象的引用,以便可以再次調用它。然後再次。以此類推,稱爲鏈接

這與iostreams使用的方案相同,用於operator<<

E.g.

#include <iostream> 
#include <sstream> 
#include <string> 
using namespace std; 

void foo(char const s[]) 
{ 
    cout << s << endl; 
} 

class StringBuilder 
{ 
private: 
    string  s_; 

    template< class Type > 
    string fastStringFrom(Type const& v) 
    { 
     stringstream stream; 
     stream << v; 
     return stream.str(); 
    } 

    char const* fastStringFrom(char const* s) 
    { 
     return s; 
    } 

    string const& fastStringFrom(string const& s) 
    { 
     return s; 
    } 

public: 
    template< class Type > 
    StringBuilder& operator<<(Type const& v) 
    { 
     s_ += fastStringFrom(v); 
     return *this;     // Supports chaining. 
    } 

    operator string const&() const { return s_; } 
    operator char const*() const { return s_.c_str(); } 
}; 

int main() 
{ 
    typedef StringBuilder S; 

    foo(S() << "6*7 = " << 6*7 << "."); // Any number of arguments. 
} 

相反轉換參數值,以文字,你就去做什麼,那就是你需要的。例如,對於一組固定的可能類型,您可以將參數存儲在集合中。

如果您不需要支持Visual C++編譯器,那麼也可以使用C++ 11 可變參數模板

0

您可以:

  • 如果你使用C++ 11可以使用可變參數模板,否則......
  • 提供重載
  • 其默認一些哨兵值,您可以識別ALA f(const T& v1 = missing, const T& v2 = missing, ...) { if (v5 != missing) ...
  • 創建可任選地從數據類型構造並具有布爾一個簡單的輔助模板使用參數來跟蹤它是否是
    • 您可能需要支持沒有默認構造函數的類型,方法是使用新建/刪除(簡單且安全但緩慢)或者將對齊的緩衝區放置到new中,手動銷燬等(錯誤且更容易出錯但更快)
  • 一些編譯器具有可變參數宏支持
  • 如果你準備改變調用語法一點,你可以使用任意數量的事情:
    • 接受載體(使用工會或變體,如果類型不同)
    • 接受的陣列(可能使用template <size_t N> void f(T (&data)[N]) { ... }特技有編譯器可以自動提供數組的大小)
    • 某種LHS的反對其可使用操作者提供額外的值,如operator,operator<<