C++:犰狳列矩阵初始化不明确

Posted

技术标签:

【中文标题】C++:犰狳列矩阵初始化不明确【英文标题】:C++: Armadillo column matrix initialization ambiguous 【发布时间】:2016-04-07 03:47:39 【问题描述】:

我定义了一个犰狳矩阵,并尝试根据其manual 通过初始化列表对其进行初始化。

除非我尝试定义列矩阵,否则没关系。

为什么会模棱两可?

#include <armadillo>

int main()

    // ok : square matrix
    arma::mat A=1.0,2.0,3.0,4.5;

    // ok: row matrix
    arma::mat B=3.5,4.0;

    // error: conversion from ‘<brace-enclosed initializer list>’ to 
    // ‘arma::mat aka arma::Mat<double>’ is ambiguous
    arma::mat C=3.5,4.0;

    // ok: column matrix
    arma::mat D=arma::mat(3.5,4.0).t();

    return 0;

【问题讨论】:

【参考方案1】:

这是 C++11/14 标准的问题。因为每个内部集合中只有一个元素,所以标准本质上说3.5,4.0 也可以解释为3.5,4.0。换句话说,3.5 可以隐式转换为double(3.5)。这导致了两个构造函数之间的歧义。

一种可能的解决方案是使用 Armadillo 列向量构造函数:

arma::mat C = arma::colvec( 3.5, 4.0 );

【讨论】:

【参考方案2】:

我猜这与 C++ 中的数组定义有关,而不是犰狳。 您似乎正在按数组初始化矩阵。因此,您的正确值必须是 C++ 标准的明确数组。让我们看看您的第三个定义的正确值:3.5,4.0 这并不意味着 1*2 列矩阵,第一行为 3.5,第二行为 4.0。它表示具有两行分别以 3.5 和 4.0 开始的任意矩阵。你可能偶尔会看到这样的定义:double d_array[2][6] = 3.5,4.0; 只有d_array 中每一行的第零个元素被初始化。由于这个正确的值可以给任何两行或更多的二维数组,它是不确定的,不能给矩阵初始化器。 我不确定这是否有意义,如果有任何不正确的地方,请通过在下面评论这个答案来通知我。

【讨论】:

我不同意你的观点,因为这段代码完全适用于方阵。如果我在没有额外包装的情况下放置数字,那将定义一个行矩阵。 operator =的犰狳相关代码可以在here或附近找到。 @mtall,是否存在任何其他解决方案或 `arma::mat(3.5,4.0).t();是唯一的方法吗? @mtall,它奏效了。谢谢。你能把它作为答案留下来让我结束这个问题吗? @mtall 感谢您的指正!知道什么是正确的总是感觉很好。【参考方案3】:

简单的答案:标准规范的规则。

首先,你的陈述

arma::mat C=3.5,4.0;

复制初始化一个对象C。(复制初始化不一定调用复制构造函数) 初始化器为initializer-list,采用list-initialization。 因为对象C是类,所以initializer-listconstructor首先被搜索。

armadillo::Mat&lt;eT&gt; 有两个initializer-list 构造函数

// defined in "<include-dir>/armadillo_bits/Mat_bones.hpp"
Mat(const std::initializer_list<eT>& list);
Mat(const std::initializer_list< std::initializer_list<eT> >& list);

这些是重载决议中的候选函数。 为了确定最佳可行函数,考虑了从 initializer-list 到每个参数的隐式转换的偏序。在这种情况下,使用 list-initialization sequence3.54.0 可以同时转换为 eTstd::initializer_list&lt;eT&gt;。这里重要的一点是这两种情况都有隐式转换。规范定义这种转换的顺序是最差的,这两个构造函数是最差的,换句话说,相同的顺序导致重载决议模棱两可。

【讨论】:

以上是关于C++:犰狳列矩阵初始化不明确的主要内容,如果未能解决你的问题,请参考以下文章

armadillo C++:从数组初始化矩阵

犰狳 - 初始化矩阵并用值填充矩阵

犰狳库是不是会减慢矩阵运算的执行速度?

如何在犰狳 C++ 中修改矩阵中的某些列

在 C++ 中存储大矩阵(犰狳)

修改矩阵后,通过内存指针(memptr)直接访问犰狳矩阵的条目不起作用