我有这样的麻烦,当我们开始使用新的C ++ 11时,编译器(GCC)说这段代码错了,但它在旧版本中运行正常:(
std::list<CCPoint> createPointArray(int count, ...) {
CCPoint val;
std::list<CCPoint*> arr;
va_list vl;
va_start(vl,count);
for (int i=0;i<count;i++)
{
val = va_arg(vl,CCPoint*);
arr.push_back(*val);
}
va_end(vl);
return arr;
}
这就是方式,我正在使用它:
createPointArray(3, &CCPoint(1.3,2.7), &CCPoint(1.5,1.75), &CCPoint(1.9,1.3))
编译器告诉我下一步:
Error 486 error : taking address of temporary [-fpermissive] (col 57)
为什么&amp; CCPoint(1.3,2.7)出现问题?如何更改此代码以使其适用于C ++ 11及更早版本?
P.S。:我正在使用Marmalade 7.3.1,Visual Studio 2010,cocos2d-x v2.2.1
答案 0 :(得分:3)
如果您正在使用C ++ 11,请不要首先编写此功能。新的初始化列表构造函数将为您处理它:
std::list<CCPoint> l { CCPoint(1.3,2.7), CCPoint(1.5, 1.75), CCPoint(1.9, 1.3) };
如果由于某种原因想要继续使用这个可变参数函数,你可以停止编译器抱怨你没有获取临时地址而获取临时地址。
你可以通过值传递对象,尽管ecatmur指出这是实现定义的(如果复制和移动构造函数和析构函数都是微不足道的话应该没问题):
std::list<CCPoint> m = createPointArray(3, CCPoint(1.3,2.7),
CCPoint(1.5,1.75), CCPoint(1.9,1.3));
(你已经在你的函数中将val声明为CCPoint实例 - 而不是指针 - 只需更改va_arg类型即可。)
否则,您可以直接传递双值:
std::list<CCPoint> m = createPointArray(3, 1.3, 2.7, 1.5, 1.75, 1.9, 1.3);
std::list<CCPoint> createPointArray(int count, ...) {
std::list<CCPoint> arr;
va_list vl;
va_start(vl,count);
for (int i=0;i<count;i++) {
double x = va_arg(vl,double);
double y = va_arg(vl,double);
arr.push_back(CCPoint(x,y));
}
va_end(vl);
return arr;
}
答案 1 :(得分:1)
你只是不能把一个临时的地址,究竟是什么错误说的。您可以通过传递值来轻松解决此问题:
std::list<CCPoint> createPointArray(int count, ...) {
std::list<CCPoint> arr;
va_list vl;
va_start(vl,count);
for (int i=0;i<count;i++)
arr.push_back(va_arg(vl,CCPoint));
va_end(vl);
return arr;
}
createPointArray(3, CCPoint(1.3,2.7), CCPoint(1.5,1.75), CCPoint(1.9,1.3));
而且,你现在不需要这样的功能:
std::list<CCPoint> arr {CCPoint(1.3,2.7), CCPoint(1.5,1.75), CCPoint(1.9,1.3)};
更简单
答案 2 :(得分:0)
暂时使用prvalue的地址是非法的(在C ++ 03中也是非法的)。
您可以使用强制转换将值类别更改为左值:
createPointArray(3,
&static_cast<CCPoint const&>(CCPoint(1.3,2.7)),
&static_cast<CCPoint const&>(CCPoint(1.5,1.75)),
&static_cast<CCPoint const&>(CCPoint(1.9,1.3)));
这将适用于C ++ 03和C ++ 11,因为临时对象在封闭的完整表达式结束之前不会被销毁。
因为您通过指针将对象传递给const
,所以您应该使用va_arg(vl, CCPoint const*)
提取它们。
答案 3 :(得分:0)
在C ++ 11中,只需使用initializer_list
:
std::list<CCPoint> l { CCPoint(1.3, 2.7), CCPoint(1.5, 1.75), CCPoint(1.9, 1.3) };
在C ++ 03中,您可能有一个数组,然后使用以下命令初始化您的列表:
const CCPoint points[] = { CCPoint(1.3, 2.7), CCPoint(1.5, 1.75), CCPoint(1.9, 1.3) };
std::list<CCPoint> l(points, points + sizeof(points) / sizeof(*points));
// or std::list<CCPoint> l(points, points + 3); // error prone
// or std::list<CCPoint> l(std::begin(points), std::end(points)); // In C++11