违反va_arg

时间:2019-06-01 10:45:07

标签: c++ templates variadic-functions variadic

我正在尝试创建一个函数,该函数在参数中采用可变数量的矩阵,并将其乘以第一个。 我可以使用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)

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

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;

1 个答案:

答案 0 :(得分:3)

无论如何,我还是无法理解您究竟想从OCPChangementDeBase()方法中获得什么...也许我错了...但是在我看来,关于可变参数有一些重要的观点未知的功能。

(1)旧的C variad语法

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

因此,如果您希望在未命名的varidic列表中出现两个自变量,则只有一个,并且“下一次调用va_arg将导致访问冲突”也就不足为奇了。 / p>

(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>完全相同(或者可能更好地转换为path = os.path.dirname(r"C:\Users\ab\AppData\Local\Google\Chrome\User Data\Default\Extensions\jfpmbokkdeapjommajdfmmheiiakdlgo\0.1.7_0\manifest.json") options = webdriver.ChromeOptions() options.add_argument('--incognito') options.add_argument("--load-extension={path}") driver = webdriver.Chrome(chrome_options=options, executable_path='C:\chromedriver_win32\chromedriver.exe') driver.maximize_window() driver.get(xxxxxxxx) (如果需要,可以转换为其他类型)。< / p>