标签: variadic-functions

是否有一个与“vsnprintf”类似的函数可以与“std::string”一起使用

我没有看到可以std::string消耗va_list. va_list是否有将 a 转换为 a 的通用解决方案std::string

我见过以下形式的解决方案:

std::string vstring (const char * format, ...) {
  std::string result;

  va_list args;
  va_start(args, format);

  char buffer[1024];
  vsnprintf(buffer, sizeof(buffer), format, args);
  result = std::string(buffer);

  va_end(args);
  return result;
}
Run Code Online (Sandbox Code Playgroud)

这感觉容易出错并且很hacky。有没有办法直接std::string从 a 构建或操作va_list

注意:上述解决方案的主要问题是需要猜测我需要的内存量。我不想浪费太多或没有足够的东西。理想情况下,我想要一种std::string可以正常工作的样式不透明分配。

注意:我需要一个不需要第三方库支持的解决方案。

c++ variadic-functions stdstring

1
推荐指数
1
解决办法
2321
查看次数

即使交换参数,printf() 在 x86-64 平台上也会给出相同的输出

考虑以下代码:

#include <stdio.h>

int main() {
    printf("%lf %ld\n", 1234.0, 5678L);
    printf("%lf %ld\n", 5678L, 1234.0);
}
Run Code Online (Sandbox Code Playgroud)

两次调用都printf打印相同的 text 1234.000000 5678,这与第二次调用的代码不太匹配(可能应该是5678.0000 1234)。

我使用的是 x86-64 处理器上的 Linux 4.x,但我无法在 x86(32 位)上重现这一点。我认为它可以在 amd64 架构上的任何 Linux 系统上重现。

为什么交换的参数为 提供相同的输出printf,以及为什么它特定于 x86-64?

c printf variadic-functions

1
推荐指数
1
解决办法
174
查看次数

How can I use va_arg in a loop without knowing how many optional arguments there are in C++?

I want to write a function which takes at least two integer and returns the sum of all integer passed to the function:

int sumOfAtLeastTwoIntegers(int a, int b, ...){
   
    int sum = a+b;
    va_list ptr;
    va_start(ptr,b);
    for(){
        sum += va_arg(ptr, int)
    }

    va_end(ptr);
    return sum;
}
Run Code Online (Sandbox Code Playgroud)

I want to know how the expression in the for loop has to look like such that the loop continues until all optional arguments were added to the sum. How would I achieve this …

c++ templates variadic-functions variadic-templates

1
推荐指数
2
解决办法
116
查看次数

获取第一个传递的可变参数的地址

#include <stdarg.h>

template<typename... Args> 
void Func(Args... args)
{
// WANT: Get the address of the first argument

// TRIED:
// va_list vargs = (char*)&(args);
// va_list vargs = (char*)&(args)...;
// va_list vargs = (char*)&(args...);

// GOT:
// 'args': parameter pack must be expanded in this context
}
Run Code Online (Sandbox Code Playgroud)

我正在编写一个接受 N 个参数并对所有参数执行某些操作的函数。为此,我想获取可变参数列表的第一个元素的地址。

之后,据我所知,va_arg宏取消引用指针并va_list以假定类型的大小移动类型对象

编辑:我可能可以做这样的事情:

template<typename... Args> 
void Func(int arg1, Args... args)
{
// Code
}
Run Code Online (Sandbox Code Playgroud)

但是,这会导致更多我不想要的代码行。

c++ variadic-functions

1
推荐指数
1
解决办法
427
查看次数

如何重载带有可变数量参数的函数

我需要区分(重载)两个函数——一个接受一个const char*参数,另一个接受至少两个参数——一个const char*后跟一个或多个参数。即基本上:

void f(const char *str);
void f(const char *format, ...)
Run Code Online (Sandbox Code Playgroud)

我想要第一个版本被调用,f("hello")第二个版本被调用f("hello %d", 10)。上述重载将不起作用,因为编译器发现f("hello")歧义。

所以我试过这个:

void f(const char *str);

template<typename T>
void f(const char *str, T tt, ...);
Run Code Online (Sandbox Code Playgroud)

这使得重载解析正常工作。但我最终遇到了另一个问题。第二个函数应该转发 printf 样式使用的参数。所以我有类似的东西:

template <typename T>
void f ( const char *format, T tt, ... )
{
    (T)tt;
    va_list varlist;
    va_start(varlist, format);
    vprintf(format, varlist);
    va_end(varlist);
}
Run Code Online (Sandbox Code Playgroud)

现在第二个参数tt不再是变量参数列表的一部分,并且调用va_start()withformat 似乎不起作用

有什么办法可以实现我想要的吗?

c++ overloading variadic-functions

1
推荐指数
1
解决办法
66
查看次数

Go 不能使用 name (type []string) 作为 ...string 参数的 string 类型

我在编译这段代码时遇到了这个问题:

./greet.go:11:29: cannot use name (type []string) as type string in argument to CheckStringsAreUppercase
Run Code Online (Sandbox Code Playgroud)

但我不明白为什么。name ...string并且words ...string具有完全相同的类型。这是怎么回事?

func Greet(name ...string) string {
        helloWord := "Hello"
    
        if CheckStringsAreUppercase(name) {
            return strings.ToUpper(helloWord)
        }
    
        return helloWord
    }
    
    func CheckStringsAreUppercase(words ...string) bool {
        for _, word := range words {
            if !CheckStringIsUppercase(word) {
                return true
            }
        }
    
        return true
    }
Run Code Online (Sandbox Code Playgroud)

variadic-functions go slice

1
推荐指数
1
解决办法
4560
查看次数

为什么 printf 的 hh 和 h 长度修饰符存在?

在可变参数函数中,会发生默认参数提升。

6.5.2.2.6 如果表示被调用函数的表达式的类型不包含原型,则对每个参数执行整数提升,并将具有类型的参数float提升为double。这些称为默认参数提升。[...]

6.5.2.2.7 [...] 函数原型声明符中的省略号会导致参数类型转换在最后一个声明的参数之后停止。默认参数提升是在尾随参数上执行的。

所以,

signed char c = 123;
int         i = 123;
float       f = 123;
double      d = 123;

printf("%d\n", i);   // ok
printf("%d\n", c);   // ok, even though %d expects int.
printf("%f\n", d);   // ok
printf("%f\n", f);   // ok, even though %f expects double.
Run Code Online (Sandbox Code Playgroud)

那么为什么( ) 和( )有一个printf长度修饰符呢?charhhshorth


章节编号参见 N2176。

c printf variadic-functions integer-promotion

1
推荐指数
1
解决办法
105
查看次数

处理“std::size_t”类型的可变参数函数参数

我正在尝试掌握可变函数/模板参数的窍门。但是,在下面的两个函数中,我很困惑为什么SumIndices不能编译(我收到编译器错误“expansion pattern \xe2\x80\x98std::size_t\xe2\x80\x99 {aka \xe2\x80\x98long unsigned int\xe2\x80\x99} 不包含参数包”)而包含SumValues

\n
template <typename ...t_data_type>\nconstexpr auto SumValues(t_data_type ..._values) { \n  return (_values + ...); \n}\n\nconstexpr auto SumIndices(std::size_t ..._indices) { \n  return (_indices + ...); \n}\n
Run Code Online (Sandbox Code Playgroud)\n

如果有人能为我澄清这个困惑,我将不胜感激!

\n

c++ variadic-functions variadic-templates c++17 c++20

1
推荐指数
1
解决办法
514
查看次数

为什么在 Rust 中使用可变参数链接和调用 C 函数会导致随机函数被调用?

我正在玩 Rust FFI,我试图将printf具有可变参数的 C 函数与我的 Rust 可执行文件链接起来。运行可执行文件后,我目睹了一些奇怪的行为。

这是我的 Rust 代码:

use cty::{c_char, c_int};

extern "C" {
    fn printf(format: *const c_char, ...) -> c_int;
}

fn main() {
    unsafe {
        printf("One number: %d\n".as_ptr() as *const i8, 69);
        printf("Two numbers: %d %d\n".as_ptr() as *const i8, 11, 12);
        printf(
            "Three numbers: %d %d %d\n".as_ptr() as *const i8,
            30,
            31,
            32,
        );
    }
}
Run Code Online (Sandbox Code Playgroud)

这是运行后的输出cargo run

cargo run
   Compiling c-bindings v0.1.0 (/home/costin/Rust/c-bindings)
    Finished dev [unoptimized + debuginfo] target(s) in 0.20s …
Run Code Online (Sandbox Code Playgroud)

function ffi variadic-functions rust rust-cargo

1
推荐指数
1
解决办法
531
查看次数

C 中的 printf() 使用什么调用约定?

因此,我一直在练习使用 CDECL 和 STDCALL 调用约定在 FASMW 中编写简单的子例程,这让我想知道printfC 中的函数将使用什么。

此外,x86 32 位汇编中的函数定义也很棒。如果这还不算过分的话。

c x86 assembly variadic-functions calling-convention

1
推荐指数
1
解决办法
939
查看次数