gpt4 book ai didi

c++ - C++中可变数量的参数?

转载 作者:IT老高 更新时间:2023-10-28 11:25:34 24 4
gpt4 key购买 nike

如何编写一个接受可变数量参数的函数?这可能吗,怎么做?

最佳答案

C++11 中有两个新选项,如 Variadic arguments 替代品部分中的引用页面指出:

  • Variadic templates can also be used to create functions that take variable number ofarguments. They are often the better choice because they do not impose restrictions onthe types of the arguments, do not perform integral and floating-point promotions, andare type safe. (since C++11)
  • If all variable arguments share a common type, a std::initializer_list provides aconvenient mechanism (albeit with a different syntax) for accessing variable arguments.

以下是显示两种选择的示例 ( see it live ):

#include <iostream>
#include <string>
#include <initializer_list>

template <typename T>
void func(T t)
{
std::cout << t << std::endl ;
}

template<typename T, typename... Args>
void func(T t, Args... args) // recursive variadic function
{
std::cout << t <<std::endl ;

func(args...) ;
}

template <class T>
void func2( std::initializer_list<T> list )
{
for( auto elem : list )
{
std::cout << elem << std::endl ;
}
}

int main()
{
std::string
str1( "Hello" ),
str2( "world" );

func(1,2.5,'a',str1);

func2( {10, 20, 30, 40 }) ;
func2( {str1, str2 } ) ;
}

如果您使用 gccclang 我们可以使用 PRETTY_FUNCTION magic variable显示函数的类型签名,这有助于理解正在发生的事情。例如使用:

std::cout << __PRETTY_FUNCTION__ << ": " << t <<std::endl ;

将导致示例中的可变参数函数遵循 int ( see it live ):

void func(T, Args...) [T = int, Args = <double, char, std::basic_string<char>>]: 1
void func(T, Args...) [T = double, Args = <char, std::basic_string<char>>]: 2.5
void func(T, Args...) [T = char, Args = <std::basic_string<char>>]: a
void func(T) [T = std::basic_string<char>]: Hello

在 Visual Studio 中,您可以使用 FUNCSIG .

更新 Pre C++11

Pre C++11 std::initializer_list 的替代品将是 std::vector或其他standard containers之一:

#include <iostream>
#include <string>
#include <vector>

template <class T>
void func1( std::vector<T> vec )
{
for( typename std::vector<T>::iterator iter = vec.begin(); iter != vec.end(); ++iter )
{
std::cout << *iter << std::endl ;
}
}

int main()
{
int arr1[] = {10, 20, 30, 40} ;
std::string arr2[] = { "hello", "world" } ;
std::vector<int> v1( arr1, arr1+4 ) ;
std::vector<std::string> v2( arr2, arr2+2 ) ;

func1( v1 ) ;
func1( v2 ) ;
}

可变参数模板的替代方案是variadic functions尽管它们不是类型安全的,而且通常是error prone and can be unsafe to use但唯一的其他潜在替代方法是使用 默认参数,尽管使用有限。下面的示例是链接引用中示例代码的修改版本:

#include <iostream>
#include <string>
#include <cstdarg>

void simple_printf(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);

while (*fmt != '\0') {
if (*fmt == 'd') {
int i = va_arg(args, int);
std::cout << i << '\n';
} else if (*fmt == 's') {
char * s = va_arg(args, char*);
std::cout << s << '\n';
}
++fmt;
}

va_end(args);
}


int main()
{
std::string
str1( "Hello" ),
str2( "world" );

simple_printf("dddd", 10, 20, 30, 40 );
simple_printf("ss", str1.c_str(), str2.c_str() );

return 0 ;
}

使用 可变参数函数 还附带限制您可以传递的参数,这在 draft C++ standard 中有详细说明。在 5.2.2 小节 函数调用 小节 7:

When there is no parameter for a given argument, the argument is passed in such a way that the receiving function can obtain the value of the argument by invoking va_arg (18.7). The lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) standard conversions are performed on the argument expression. After these conversions, if the argument does not have arithmetic, enumeration, pointer, pointer to member, or class type, the program is ill-formed. If the argument has a non-POD class type (clause 9), the behavior is undefined. [...]

关于c++ - C++中可变数量的参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1657883/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com