#define exampleA(buf, args...) \
exampleB(buf, ##args); \
}
#endif
Run Code Online (Sandbox Code Playgroud)
在 exampleB 函数声明为 exampleB(char* buf, ...) 的情况下工作。但我需要将声明更改为 exampleB(char* buf, va_list args)。如何相应地更改宏?
我希望在 C 中创建一个可变参数函数,允许执行如下操作:
Send({1,2,3,4,5});
Send({4,5,2});
Send({1,1,1,1,1,1,1,1,1,1,1,1,1});
Run Code Online (Sandbox Code Playgroud)
请注意,没有长度输入,并且数组是内联放置的,并且没有任何设置或创建任何变量
目前我正在使用正式的可变参数选项,如下所示(来自此处的示例),这非常方便,但也容易出现有时难以调试的错误,例如忘记放置num_args(仍然编译)、放置错误数量的元素等。
int sum(int num_args, ...) {
int val = 0;
va_list ap;
int i;
va_start(ap, num_args);
for(i = 0; i < num_args; i++) {
val += va_arg(ap, int);
}
va_end(ap);
return val;
}
Run Code Online (Sandbox Code Playgroud) 我正在努力理解 C++ 中的模板参数包扩展。出于演示目的,我想编写一个函数来打印签名中使用的类型的人类可读名称(任何签名 - 这就是可变参数模板的用武之地)。
#include <boost/type_index.hpp>
std::string SignatureToString()
{
return std::string();
}
template<typename Arg1, typename... Args>
std::string SignatureToString(const Arg1&, Args&&... args)
{
std::string strRetVal = boost::typeindex::type_id<Arg1>().pretty_name();
std::string strRemainingSignature = SignatureToString(args...); // expanding parameters works
if (!strRemainingSignature.empty())
{
strRetVal = strRetVal + ", " + strRemainingSignature;
}
return strRetVal;
}
class cDog {/* ... */};
int main(int /*argc*/, char* /*argv*/[])
{
int i(0);
std::string str;
//cDog someDog("Harry"); // don't want to construct this dummy object!
std::cout << "GetSignature(): '" << …Run Code Online (Sandbox Code Playgroud) 我知道关于这个话题已经有很多问题,但到目前为止,我没有找到令人满意地回答以下问题的回答.给出以下代码.
#include <map>
template<typename T, typename K>
std::map<T, K> map()
{
return std::map<T, K>();
}
template<typename T, typename...K>
std::map<T, decltype(map<K...>())> map()
{
return std::map<T, decltype(map<K...>())>();
}
int main(int argc, char **argv)
{
std::map<int, int> m2 = map<int, int>();
std::map<int, std::map<int, int>> m3 = map<int, int, int>();
std::map<int, std::map<int, std::map<int, int>>> m4 = map<int, int, int, int>(); // <- Compile Error here
return 0;
}
Run Code Online (Sandbox Code Playgroud)
打电话给
map<int, int, int>()
Run Code Online (Sandbox Code Playgroud)
应归还一个物体
std::map<int, std::map<int, int>>
Run Code Online (Sandbox Code Playgroud)
这适用于最多三个模板参数.如代码中所述,调用具有四个模板参数的pair函数失败,g ++(5.1.0)返回以下错误.
main.cpp: In function 'int main(int, char**)': …Run Code Online (Sandbox Code Playgroud) 我的 nullPointcheck 函数:
template<typename T, typename... Args>
bool __nullPointCheck(T first, Args... args)
{
bool ret = true;
va_list vl;
auto n = sizeof...(args);
va_start(vl, n);
for (auto i = 0; i <= n; ++i)
{
auto p = va_arg(vl, T);
if (!p)
{
ret = false;
}
}
va_end(vl);
return ret;
}
Run Code Online (Sandbox Code Playgroud)
但我收到 ndk 构建错误,如下所示:
'va_start' used in function with fixed args
va_start(vl, n);
Run Code Online (Sandbox Code Playgroud)
当我将 va_start 中的第二个参数更改为第一个参数时,如下所示:
va_start(vl, first);
Run Code Online (Sandbox Code Playgroud)
ndk-build导出报错如下:
'va_start' used in function with fixed args
va_start(vl, first);
^ …Run Code Online (Sandbox Code Playgroud) 我的问题很简单.
核心Java中是否有一个方法可以执行以下代码:
<T> T[] asArray(T... values) {
return values;
}
Run Code Online (Sandbox Code Playgroud)
我尝试在Arrays类中寻找它,但似乎没有这样的方法.
给你一个背景:
之前使用过该代码的人认为varargs比类构造函数中的常规数组更好(即使它应该是一个数组).现在我必须添加另一个通用数组作为构造函数的最后一个参数,从而转换此代码:
public Clazz(String... values) {
}
Run Code Online (Sandbox Code Playgroud)
对此
public <T> Clazz(String[] values, T[] additionalParameters)
Run Code Online (Sandbox Code Playgroud)
因此,我需要重构使用此构造函数的所有位置.更糟糕的是,有一些其他类遵循相同的模式,我需要在将来的某个时候修改它们.这就是上面提到的方法asArray可以提供的帮助.
我知道最好在每次出现时用显式数组创建替换varargs(这也就是我要做的事情),但我仍然想知道是否已经存在这样的方法(仅仅是出于好奇心).
我现在正在研究泛型,根据我的理解,我们使用泛型,所以我们可以避免/消除强制转换的需要,那么为什么在添加项目和链接列表时我必须进行强制转换?
public class ThisIsCode<E> implements Code{
LinkedList<E> list = new LinkedList<>();
public final void add(E... item) {
List<E> thingie = new LinkedList<>();
for (E i: item) {
thingie.add((E) item);
}
list.add((E)thingie);
}
Run Code Online (Sandbox Code Playgroud)
我也必须在这个方法中进行转换,并在数组中?我不认为我应该将项目放入数组中,所以我有点困惑.
public void addSingle(Object item) {
add((E[]) item);
}
Run Code Online (Sandbox Code Playgroud) 我遇到了下面用C++编写的这个函数.trace()使用任意数量的参数调用函数会打印每个参数的值以及格式中参数的名称
name1:value1 | name2:value2等等.
我想了解这段代码是如何工作的,什么有的像双&符号的语法&&,__VA_ARGS__意思.谢谢!
#define tr(...) trace(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void trace(const char* name, Arg1&& arg1){
cout << name << " : " << arg1 << endl;
}
template <typename Arg1, typename... Args>
void trace(const char* names, Arg1&& arg1, Args&&... args){
const char* comma = strchr(names + 1, ',');
cout.write(names, comma-names) << " : " << arg1 << " | " ;
trace(comma+1, args...);
}
Run Code Online (Sandbox Code Playgroud) 为什么我在此代码中出现此错误?
def fun(a,*b):
print(a,b)
fun(1,x=4,y=5)
Run Code Online (Sandbox Code Playgroud)
当代码执行时我得到这个错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: fun() got an unexpected keyword argument 'x'
Run Code Online (Sandbox Code Playgroud) 请注意以下潜在的愚蠢问题:
我有一个方法,使用String.format()方法格式化一些文本.目前,它接收两个参数,所以我有两个"%s"参数来创建我想要的任何文本.
但有人可能想用我的方法使用3个参数,或4或100.如何将传递的参数的长度作为varargs获取到String.format()方法的长度,以便在传递3个参数的情况下,将有3个"%s"而不是当前的2个; 或4或100.
如何获取传递给String.format()方法的参数数量,以便其中的文本根据需要自动添加"%s"?因为参数只是作为常规参数传递,而不是作为数组或类似的传递.如何获取参数数组的长度?
PS.这很重要 - 我不是在谈论获取(String ...参数) - 没有这样的事情 - 当有人调用你的方法时,它使用实际参数,"String ... arguments"不可用于抓取和获得它的长度.
我意识到这是一个制定得很糟糕的问题,因为我没有在我面前的代码进一步解释,但这已经困扰了我很长一段时间 - 你如何获得传递给方法的参数数量?
对于这样的事情:
String.format(SomeObject.SomeString, param1, param2,...,param 100)
Run Code Online (Sandbox Code Playgroud)
编辑:SomeObject.SomeString声明如下:
String SomeString = "Blah blah %s blah blah blah %s";
所以它有两个正在硬编码的参数.
当有人使用它时,你如何自定义SomeObject.SomeString以便"知道"已经将多少参数传递给String.format()方法(以便SomeObject.SomeString知道动态添加多少%s)?