2012-08-09 78 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<<