C ++:Armadillo列矩阵初始化模糊不清

时间:2016-04-07 03:47:39

标签: c++ templates c++11 armadillo

我定义了一个犰狳矩阵,我尝试根据其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;
}

3 个答案:

答案 0 :(得分:4)

这是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} );

答案 1 :(得分:2)

我想这与C ++中的数组定义有关,而不是与Armadillo有关 看来你是用数组初始化矩阵。因此,正确的值必须是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中每行的第0个元素。由于这个正确的值可以赋予任何两行或更多行的2D数组,因此它不是明确的,也不能用于矩阵初始化器。
我不确定它是否有意义,如果有任何不正确的地方,请通过评论下面的答案注意我。

答案 2 :(得分:2)

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

首先,你的陈述

arma::mat C={{3.5},{4.0}};

copy-initialize 一个对象C。(复制初始化不一定会调用复制构造函数) 初始化程序是 initializer-list ,并使用 list-initialization 。 由于对象C是类,因此首先搜索 initializer-list construtor

armadillo::Mat<eT>有两个初始化列表 构造函数

// 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);

这些是重载决策中的候选功能。 为了确定最佳可行函数,考虑从初始化列表到每个参数的隐式转换的部分顺序。在这种情况下,使用列表初始化 序列{3.5}{4.0}可以同时转换为eTstd::initializer_list<eT>。这里重点是两种情况都有隐含的转换。规范定义了这种转换具有最差的顺序,并且这两个构造函数是最差的,换句话说,相同的顺序会导致模糊的重载决策。