如果我定义一些宏:
#define foo(args...) ({/*do something*/})
Run Code Online (Sandbox Code Playgroud)
有没有办法实际循环args而不是传递给另一个函数?就像是
#define foo(args...) \
{ \
for (int i = 0; i < sizeof(args); ++i) { \
/*do something with args[i]*/ \
} \
}
Run Code Online (Sandbox Code Playgroud) 我不明白那种语法.试图谷歌各种单词加"......"是没用的.
ruby exec()函数为其第二个参数采用vararg来为正在执行的程序提供参数.但是,我想传递一组参数(出于各种原因).我可以解决这个问题,只需给exec一个完整的字符串,但它涉及shell(并转义可能的参数).另外,据我所知,将参数折叠为一个字符串会将它们作为一个参数传递给我的程序 - 我希望保留它们的清晰度.是否可以将数组传递给ruby函数中的varargs参数?(请注意,在这种情况下,我无法修改exec()以接受任何换行或移位).
我想在javascript中使用可变数量的参数创建一个函数.下一个例子是我想如何调用这个函数:
myFunction(1,2);
myFunction(1,2,3);
myFunction(1,2,3,4);
myFunction(1,2,3,4,5);
myFunction(1,2,3,4,5,6);
Run Code Online (Sandbox Code Playgroud)
谁知道如何定义这个功能?
我有一个函数,它带有一个默认值的参数.现在我还希望它采用可变数量的参数并将它们转发给其他函数.默认值的函数参数必须是最后一个,所以...我可以将该参数放在可变参数包之后,编译器会在调用函数时检测我是否提供它吗?
(假设包不包含最后一个参数的类型.如果需要,我们可以假设,因为这种类型一般不应该被称为给用户,否则它反正认为我的接口错误使用.. ..)
template <class... Args>
void func (Args&&... args, SomeSpecialType num = fromNum(5))
{
}
Run Code Online (Sandbox Code Playgroud) c++ default-value variadic-functions variadic-templates c++11
我正在编写一个类似于boost :: promote的促销模板别名,但是对于C++ 11.这样做的目的是在从varidic函数检索参数时避免警告.例如
template <typename T>
std::vector<T> MakeArgVectorV(int aArgCount, va_list aArgList)
{
std::vector<T> args;
while (aArgCount > 0)
{
args.push_back(static_cast<T>(va_arg(aArgList, Promote<T>)));
--aArgCount;
}
return args;
}
Run Code Online (Sandbox Code Playgroud)
Promote模板别名在可变参数的默认参数提升之后提升类型:1)小于int的整数被提升为int 2)float被提升为double
我的问题是可以提升标准C++枚举,但不提升C++ 11枚举类(编译器不会生成警告).我希望Promote使用常规枚举但忽略C++ 11枚举类.
如何区分我的Promote模板别名中的枚举类和枚举?
我还没有找到解决这个问题的优雅方法.我有一个抽象类,其他几个类继承了一个抽象方法,可以包含0到4-5个不同类型的参数.
public abstract class Item {
public abstract void use();
}
Run Code Online (Sandbox Code Playgroud)
例如,我有一个继承了这个并且在重写use()时没有参数的Book类,我有一个Key类,它继承并在重写时将String和Queue作为参数...
我已经尝试过使用泛型,但是当它实际上取决于类时,我必须输入使用的数字,例如Item.
public abstract class Item<T,U> {
public abstract void use(T arg1, U arg2); //Number of arguments/types could be more or less
}
Run Code Online (Sandbox Code Playgroud)
我已经尝试发送一个对象的变量列表,但对象类型总是可变的,我不确定在继承类中接收的语法.
public abstract class Item<T> {
public abstract void use(T... arguments);
}
public class Book extends Item<?> {
public void use(?);
}
public class Book extends Item<String, Queue> { //Wrong number of arguments since I can't use Item<T...>
public void use(String str, Queue q); //fails
} …Run Code Online (Sandbox Code Playgroud) 在玩优化设置时,我注意到一个有趣的现象:采用可变数量的参数(...)的函数似乎永远不会被内联.(显然这种行为是特定于编译器的,但我已经在几个不同的系统上进行了测试.)
例如,编译以下小程序:
#include <stdarg.h>
#include <stdio.h>
static inline void test(const char *format, ...)
{
va_list ap;
va_start(ap, format);
vprintf(format, ap);
va_end(ap);
}
int main()
{
test("Hello %s\n", "world");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
似乎总是会test在生成的可执行文件中出现(可能是损坏的)符号(在MacOS和Linux上以C和C++模式使用Clang和GCC进行测试).如果修改了签名test()以获取传递给的普通字符串printf(),那么-O1两个编译器都会按照您的预期向上内联函数.
我怀疑这与用于实现varargs的巫术魔法有关,但是通常这样做对我来说是个谜.任何人都可以告诉我编译器通常如何实现vararg函数,以及为什么这似乎阻止了内联?
我正在阅读有关varargs堆污染的内容,我并不真正了解varargs或non-reifiable类型将如何解决那些在没有通用性的情况下尚未存在的问题.的确,我可以很容易地取代
public static void faultyMethod(List<String>... l) {
Object[] objectArray = l; // Valid
objectArray[0] = Arrays.asList(42);
String s = l[0].get(0); // ClassCastException thrown here
}
Run Code Online (Sandbox Code Playgroud)
同
public static void faultyMethod(String... l) {
Object[] objectArray = l; // Valid
objectArray[0] = 42; // ArrayStoreException thrown here
String s = l[0];
}
Run Code Online (Sandbox Code Playgroud)
第二个只是使用数组的协方差,这实际上是问题所在.(即使List<String>是可以恢复的,我想它仍然是子类,Object我仍然可以将任何对象分配给数组.)当然我可以看到两者之间有一点差别,但是这个代码是错误的,无论是是否使用泛型.
它们对堆污染的意义是什么(它让我考虑内存使用情况,但他们谈到的唯一问题是潜在的类型不安全),它与使用数组协方差的任何类型违规有何不同?
请考虑以下代码行:
public static void main(String[] args) {
foo(1,2,3);
System.out.println("-------------------------------------");
foo(new Integer(1), new Integer(2), new Integer(3));
System.out.println("-------------------------------------");
foo(new Integer[]{1,2,3});
System.out.println("-------------------------------------");
foo(new Integer[] {new Integer(1), new Integer(2), new Integer(3)});
}
public static void foo(Object... bar) {
System.out.println("bar instanceof Integer[]:\t" + (bar instanceof Integer[]));
System.out.println("bar[0] instanceof Integer:\t" + (bar[0] instanceof Integer));
System.out.println("bar.getClass().isArray():\t" + bar.getClass().isArray());
}
Run Code Online (Sandbox Code Playgroud)
此代码段的输出是:
bar instanceof Integer[]: false
bar[0] instanceof Integer: true
bar.getClass().isArray(): true
-------------------------------------
bar instanceof Integer[]: false
bar[0] instanceof Integer: true
bar.getClass().isArray(): true
-------------------------------------
bar instanceof Integer[]: true
bar[0] …Run Code Online (Sandbox Code Playgroud) java ×4
c++ ×3
c ×2
c++11 ×2
autoboxing ×1
generics ×1
inheritance ×1
javascript ×1
macros ×1
memory ×1
ruby ×1
templates ×1
variadic ×1