gpt4 book ai didi

c++ - va_arg 上的访问冲突

转载 作者:太空狗 更新时间:2023-10-29 21:09:59 29 4
gpt4 key购买 nike

我正在尝试创建一个函数,该函数在参数中采用可变数量的矩阵并将这些矩阵乘以第一个。我可以使用 va_arg 读取第一个,但下一次调用 va_arg 将导致访问冲突。

这是我声明方法的方式:

template<class MType>
static CMatrice<MType> COperationsComplexesMatricesPassages::OCPChangementDeBase
(CMatrice<MType> & MATVecteur, unsigned int uiNbMatricesPassages,
CMatricePassage<MType> MAPMatrices...)

我是这样调用它的:

COperationsComplexesMatricesPassages::OCPChangementDeBase(mat1, 2, matP1, matP2)

异常出现在我的方法主体中 for(...) 的第一个 va_arg 上。这是我的方法的代码:

unsigned int uiIndice;
unsigned int uiBaseArriveePrecedente;

va_list args;
va_start(args, MAPMatrices);

CMatrice<MType> MATResult(MATVecteur);
CMatricePassage<MType> MAPMatricePass = va_arg(args, CMatricePassage<MType>);

MATResult = MATResult * MAPMatricePass;

uiBaseArriveePrecedente = MAPMatricePass.MAPGetBaseArrivee();
for (uiIndice = 1; uiIndice < uiNbMatricesPassages; uiIndice++) {
CMatricePassage<MType> MAPMatricePass2 = va_arg(args, CMatricePassage<MType>);
if (uiBaseArriveePrecedente != MAPMatricePass2.MAPGetBaseDepart()) {
CException EXCError(EXC_ChangementImpossible);
throw EXCError;
}
uiBaseArriveePrecedente = MAPMatricePass2.MAPGetBaseArrivee();
MATResult = MATResult * MAPMatricePass2;
}

return MATResult;

最佳答案

我不明白你到底想从你的 OCPChangementDeBase() 得到什么方法,无论如何......也许我错了......但在我看来,关于可变参数函数,有几个重要的点你不知道。

(1) 旧的 C 变量语法

void foo (int a, int b...)

并不意味着 b是整数的可变列表。

该声明等同于(最后一个逗号是可选的)

void foo (int a, int b, ...)

所以,对于这两个声明,您有一个 b整数(单个 b 整数)和可变参数的未命名列表。

所以给你方法

template<class MType>
static CMatrice<MType>
COperationsComplexesMatricesPassages::OCPChangementDeBase
(CMatrice<MType> & MATVecteur, unsigned int uiNbMatricesPassages,
CMatricePassage<MType> MAPMatrices...)

并调用它

COperationsComplexesMatricesPassages::OCPChangementDeBase(mat1, 2, matP1, matP2)

你有那个

  • MATVecteur成为mat1
  • uiNbMatricesPassages成为2
  • MAPMatrices成为matP1
  • 未命名可变参数列表 ...成为matP2

因此,如果您期望在未命名的可变参数列表中有两个参数,那么您只有一个,我对“下一次调用 va_arg 将导致访问冲突”并不感到惊讶。

(2) 旧的 C 可变参数语法(基于 va_listva_argva_start)在 C++ 中仍然可用,但据我所知,它仅适用于 POD(普通旧数据)类型。

因此,据我所知,您的代码是 UB(未定义的行为),因为 matP2 (我想)不是 POD。

幸运的是,C++(从 C++11 开始)引入了与非 POD 类型兼容的可变参数模板。

所以,我想,你算把你的方法写成如下或类似的东西

template <typename MType, typename ... MTs>
static auto COperationsComplexesMatricesPassages::OCPChangementDeBase
(CMatrice<MType> & MATVecteur, MTs ... MAPMatrices)
{
auto MatResult { MatVectour };

( MatResult *= MapMatrices, ... ); // template folding; only from C++17

return MatResult;
}

您还可以添加一些约束(查找 SFINAE)来强加 MTs...类型完全是(或者,也许更好,可转换为)CMatricePassage<MType> (或其他类型,如果需要的话)。

关于c++ - va_arg 上的访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56405996/

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