Cleanup SFINAE in Array/Matrix(initializer_list) ctors and minor doc editing.

This commit is contained in:
Gael Guennebaud 2019-01-22 17:08:47 +01:00
parent db152b9ee6
commit 80f81f9c4b
10 changed files with 109 additions and 97 deletions

View File

@ -180,13 +180,13 @@ class Array
} }
#if EIGEN_HAS_CXX11 #if EIGEN_HAS_CXX11
template<typename T> protected:
enum { IsFixedSizeVectorAtCompileTime = RowsAtCompileTime != Dynamic && ColsAtCompileTime != Dynamic && IsVectorAtCompileTime == 1 };
public:
template<typename T,
typename = typename internal::enable_if<IsFixedSizeVectorAtCompileTime && internal::is_same<T, Scalar>::value>::type>
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE Array(const std::initializer_list<T>& list, explicit EIGEN_STRONG_INLINE Array(const std::initializer_list<T>& list) : Base(list) {}
typename internal::enable_if<internal::is_same<T, Scalar>::value, T>::type* = 0,
typename internal::enable_if<RowsAtCompileTime != Dynamic
&& ColsAtCompileTime != Dynamic
&& IsVectorAtCompileTime == 1, T>::type* = 0) : Base(list) {}
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Array(const std::initializer_list<std::initializer_list<Scalar> >& list) : Base(list) {} EIGEN_STRONG_INLINE Array(const std::initializer_list<std::initializer_list<Scalar> >& list) : Base(list) {}
@ -219,35 +219,39 @@ class Array
* Example: \include Array_initializer_list2_cxx11.cpp * Example: \include Array_initializer_list2_cxx11.cpp
* Output: \verbinclude Array_initializer_list2_cxx11.out * Output: \verbinclude Array_initializer_list2_cxx11.out
* *
* \sa Array::Array(const Scalar& val0, const Scalar& val1) * \sa Array(const std::initializer_list<std::initializer_list<Scalar> >&)
* \sa Array::Array(const Scalar& val0, const Scalar& val1, const Scalar& val2) */ */
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE Array(const std::initializer_list<Scalar>& list); explicit EIGEN_STRONG_INLINE Array(const std::initializer_list<Scalar>& list);
/** /** \brief Constructs an array and initializes it from the coefficients given as initializer-lists grouped by row. \cpp11
* \brief Constructs an array and initializes it by elements given by an initializer list of initializer lists \cpp11 *
* * In the general case, the constructor takes a list of rows, each row being represented as a list of coefficients:
* This constructor distinguishes between the construction of arbitrary array and arrays with one fixed dimension, *
* * Example: \include Array_initializer_list_23_cxx11.cpp
* In the general case, the constructor takes an initializer list, representing the array rows, that contains for * Output: \verbinclude Array_initializer_list_23_cxx11.out
* each row an initializer list, representing a single column, containing scalar values. Each of the inner *
* initializer lists must contain the same number of elements. * Each of the inner initializer lists must contain the exact same number of elements, otherwise an assertion is triggered.
* *
* In the case of array with one fixed dimension, an initializer list containing just one other initializer list * In the case of a compile-time column 1D array, implicit transposition from a single row is allowed.
* that contains the array elements can be passed. Therefore \c Array<int,\c Dynamic,\c 1>\c {{1,\c 2,\c 3,\c 4}} is * Therefore <code> Array<int,Dynamic,1>{{1,2,3,4,5}}</code> is legal and the more verbose syntax
* legal and the more verbose syntax \c Array<int,\c Dynamic,\c 1>\c {{1},\c {2},\c {3},\c {4}} can be avoided. * <code>Array<int,Dynamic,1>{{1},{2},{3},{4},{5}}</code> can be avoided:
* *
* \warning In the case of fixed-sized arrays, the initializer list size must be equal to the array \a rows rows * Example: \include Array_initializer_list_vector_cxx11.cpp
* and \a cols columns. * Output: \verbinclude Array_initializer_list_vector_cxx11.out
* *
* Example: \include Array_initializer_list_cxx11.cpp * In the case of fixed-sized arrays, the initializer list sizes must exactly match the array sizes,
* Output: \verbinclude Array_initializer_list_cxx11.out * and implicit transposition is allowed for compile-time 1D arrays only.
*/ *
* \sa Array(const std::initializer_list<Scalar>&)
*/
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Array(const std::initializer_list<std::initializer_list<Scalar> >& list); EIGEN_STRONG_INLINE Array(const std::initializer_list<std::initializer_list<Scalar> >& list);
#endif // end EIGEN_PARSED_BY_DOXYGEN #endif // end EIGEN_PARSED_BY_DOXYGEN
/** constructs an initialized 3D vector with given coefficients */ /** constructs an initialized 3D vector with given coefficients
* \sa Array(const std::initializer_list<Scalar>&)
*/
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2) EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2)
{ {
@ -257,7 +261,9 @@ class Array
m_storage.data()[1] = val1; m_storage.data()[1] = val1;
m_storage.data()[2] = val2; m_storage.data()[2] = val2;
} }
/** constructs an initialized 4D vector with given coefficients */ /** constructs an initialized 4D vector with given coefficients
* \sa Array(const std::initializer_list<Scalar>&)
*/
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2, const Scalar& val3) EIGEN_STRONG_INLINE Array(const Scalar& val0, const Scalar& val1, const Scalar& val2, const Scalar& val3)
{ {

View File

@ -303,13 +303,13 @@ class Matrix
} }
#if EIGEN_HAS_CXX11 #if EIGEN_HAS_CXX11
template<typename T> protected:
enum { IsFixedSizeVectorAtCompileTime = RowsAtCompileTime != Dynamic && ColsAtCompileTime != Dynamic && IsVectorAtCompileTime == 1 };
public:
template<typename T,
typename = typename internal::enable_if<IsFixedSizeVectorAtCompileTime && internal::is_same<T, Scalar>::value>::type>
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE Matrix(const std::initializer_list<T>& list, explicit EIGEN_STRONG_INLINE Matrix(const std::initializer_list<T>& list) : Base(list) {}
typename internal::enable_if<internal::is_same<T, Scalar>::value, T>::type* = 0,
typename internal::enable_if<RowsAtCompileTime != Dynamic
&& ColsAtCompileTime != Dynamic
&& IsVectorAtCompileTime == 1, T>::type* = 0) : Base(list) {}
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE Matrix(const std::initializer_list<std::initializer_list<Scalar>>& list) : Base(list) {} explicit EIGEN_STRONG_INLINE Matrix(const std::initializer_list<std::initializer_list<Scalar>>& list) : Base(list) {}
@ -358,37 +358,40 @@ class Matrix
* Example: \include Matrix_initializer_list2_cxx11.cpp * Example: \include Matrix_initializer_list2_cxx11.cpp
* Output: \verbinclude Matrix_initializer_list2_cxx11.out * Output: \verbinclude Matrix_initializer_list2_cxx11.out
* *
* \sa Matrix::Matrix(const Scalar& x, const Scalar& y, const Scalar& z) * \sa Matrix(const std::initializer_list<std::initializer_list<Scalar>>&)
* \sa Matrix::Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w) */ */
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE Matrix(const std::initializer_list<Scalar>& list); explicit EIGEN_STRONG_INLINE Matrix(const std::initializer_list<Scalar>& list);
/** /** \brief Constructs a Matrix and initializes it from the coefficients given as initializer-lists grouped by row. \cpp11
* \brief Constructs a matrix and initializes it by elements given by an initializer list of initializer lists \cpp11 *
* * In the general case, the constructor takes a list of rows, each row being represented as a list of coefficients:
* This constructor distinguishes between the construction of arbitrary matrices and matrices with one fixed dimension, *
* i.e., vectors or rowvectors. * Example: \include Matrix_initializer_list_23_cxx11.cpp
* * Output: \verbinclude Matrix_initializer_list_23_cxx11.out
* In the general case, the constructor takes an initializer list, representing the matrix rows, that contains for *
* each row an initializer list, representing a single column, containing scalar values. Each of the inner * Each of the inner initializer lists must contain the exact same number of elements, otherwise an assertion is triggered.
* initializer lists must contain the same number of elements. *
* * In the case of a compile-time column vector, implicit transposition from a single row is allowed.
* In the case of matrices with one fixed dimension, an initializer list containing just one other initializer list * Therefore <code>VectorXd{{1,2,3,4,5}}</code> is legal and the more verbose syntax
* that contains the matrix elements can be passed. Therefore \c VectorXi\c {{1,\c 2,\c 3,\c 4}} is legal and the more * <code>RowVectorXd{{1},{2},{3},{4},{5}}</code> can be avoided:
* verbose syntax \c VectorXi\c {{1},\c {2},\c {3},\c {4}} can be avoided. *
* * Example: \include Matrix_initializer_list_vector_cxx11.cpp
* \warning In the case of fixed-sized matrices, the initializer list size must be equal to the matrix \a rows rows * Output: \verbinclude Matrix_initializer_list_vector_cxx11.out
* and \a cols columns. *
* * In the case of fixed-sized matrices, the initializer list sizes must exactly match the matrix sizes,
* Example: \include Matrix_initializer_list_cxx11.cpp * and implicit transposition is allowed for compile-time vectors only.
* Output: \verbinclude Matrix_initializer_list_cxx11.out *
*/ * \sa Matrix(const std::initializer_list<Scalar>&)
*/
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE Matrix(const std::initializer_list<std::initializer_list<Scalar>>& list); explicit EIGEN_STRONG_INLINE Matrix(const std::initializer_list<std::initializer_list<Scalar>>& list);
#endif // end EIGEN_PARSED_BY_DOXYGEN #endif // end EIGEN_PARSED_BY_DOXYGEN
/** \brief Constructs an initialized 3D vector with given coefficients */ /** \brief Constructs an initialized 3D vector with given coefficients
* \sa Matrix(const std::initializer_list<Scalar>&)
*/
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z) EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z)
{ {
@ -398,7 +401,9 @@ class Matrix
m_storage.data()[1] = y; m_storage.data()[1] = y;
m_storage.data()[2] = z; m_storage.data()[2] = z;
} }
/** \brief Constructs an initialized 4D vector with given coefficients */ /** \brief Constructs an initialized 4D vector with given coefficients
* \sa Matrix(const std::initializer_list<Scalar>&)
*/
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w) EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w)
{ {

View File

@ -527,21 +527,19 @@ class PlainObjectBase : public internal::dense_xpr_base<Derived>::type
} }
#ifdef EIGEN_PARSED_BY_DOXYGEN #ifdef EIGEN_PARSED_BY_DOXYGEN
/** /** \brief Construct a row of column vector with fixed size from an initializer list of coefficients. \cpp11
* \brief Construct a vector with fixed number of rows or a rowvector with fixed number of *
* columns by passing an initializer list \cpp11 * \only_for_vectors
* *
* \only_for_vectors * \warning To construct a column (resp. row) vector of fixed length, the number of values passed through
* * the initializer list must match the the fixed number of rows (resp. columns) of \c *this.
* \warning To construct a vector or rowvector of fixed size, the number of values passed through */
* the initializer list must match the the fixed number of rows in the vector case or
* the fixed number of columns in the rowvector case. */
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE PlainObjectBase(const std::initializer_list<Scalar>& list); explicit EIGEN_STRONG_INLINE PlainObjectBase(const std::initializer_list<Scalar>& list);
/** /** \brief Constructs a Matrix or Array and initializes it by elements given by an initializer list of initializer
* \brief Constructs a Matrix or Array and initializes it by elements given by an initializer list of initializer * lists \cpp11
* lists \cpp11 */ */
EIGEN_DEVICE_FUNC EIGEN_DEVICE_FUNC
explicit EIGEN_STRONG_INLINE PlainObjectBase(const std::initializer_list<std::initializer_list<Scalar>>& list); explicit EIGEN_STRONG_INLINE PlainObjectBase(const std::initializer_list<std::initializer_list<Scalar>>& list);
#else // EIGEN_PARSED_BY_DOXYGEN #else // EIGEN_PARSED_BY_DOXYGEN

View File

@ -101,38 +101,39 @@ Matrix3f a(3,3);
\endcode \endcode
and is a no-operation. and is a no-operation.
Additionally, we also offer some constructors to initialize the coefficients of small fixed-size vectors up to size 4: Matrices and vectors can also be initialized from lists of coefficients.
Prior to C++11, this feature is limited to small fixed-size column or vectors up to size 4:
\code \code
Vector2d a(5.0, 6.0); Vector2d a(5.0, 6.0);
Vector3d b(5.0, 6.0, 7.0); Vector3d b(5.0, 6.0, 7.0);
Vector4d c(5.0, 6.0, 7.0, 8.0); Vector4d c(5.0, 6.0, 7.0, 8.0);
\endcode \endcode
If C++11 is enabled, matrices can be constructed and initialized using initializer lists. In the case of fixed-sized vectors If C++11 is enabled, fixed-size column or row vectors of arbitrary size can be initialized through a single initializer list (\link Matrix::Matrix(const std::initializer_list<Scalar>&) details \endlink):
and rowvectors a simple initializer list can be passed:
\code \code
Vector2i a {1, 2}; // A vector containing the elements {1, 2} Vector2i a {1, 2}; // A column vector containing the elements {1, 2}
Matrix<int, 4, 1> b {1, 2, 3, 4}; // A row-vector containing the elements {1, 2, 3, 4} Matrix<int, 5, 1> b {1, 2, 3, 4, 5}; // A row-vector containing the elements {1, 2, 3, 4, 5}
Matrix<int, 1, 4> c {1, 2, 3, 4}; // A vector containing the elements {1, 2, 3, 4} Matrix<int, 1, 5> c {1, 2, 3, 4, 5}; // A column vector containing the elements {1, 2, 3, 4, 5}
\endcode \endcode
In the case of fixed or dynamically sized matrices an initializer list containing an initializer list for each row In the general case of matrices and vectors with either fixed or runtime sizes,
can be passed. If the matrix is fixed-sized, the number of elements that are passed must match the dimensions. coefficients have to be grouped by rows and passed as an initializer list of initializer list (\link Matrix::Matrix(const std::initializer_list<std::initializer_list<Scalar>>&) details \endlink):
\code \code
MatrixXi a { MatrixXi a { // construct a 2x2 matrix
{1, 2}, // first row {1, 2}, // first row
{3, 4} // second row {3, 4} // second row
}; };
Matrix<double, 2, 3> b { Matrix<double, 2, 3> b {
{2.0, 3.0, 4.0}, {2, 3, 4},
{5.0, 6.0, 7.0}, {5, 6, 7},
}; };
\endcode \endcode
In the case of vectors and rowvectors, the following shorthand notation can be used: For column or row vectors, implicit transposition is allowed.
This means that a column vector can be initialized from a single row:
\code \code
VectorXd a {{1.5, 2.5, 3.5}}; // A vector with 3 rows VectorXd a {{1.5, 2.5, 3.5}}; // A column-vector with 3 coefficients
RowVectorXd b {{1.0, 2.0, 3.0, 4.0}}; // A rowvector with 4 columns RowVectorXd b {{1.0, 2.0, 3.0, 4.0}}; // A row-vector with 4 coefficients
\endcode \endcode
\section TutorialMatrixCoeffAccessors Coefficient accessors \section TutorialMatrixCoeffAccessors Coefficient accessors

View File

@ -0,0 +1,5 @@
ArrayXXi a {
{1, 2, 3},
{3, 4, 5}
};
cout << a << endl;

View File

@ -1,6 +0,0 @@
Array<int, 2, 3> a {
{1, 2, 3},
{3, 4, 5}
};
Array<int, Dynamic, 1> v {{1, 2, 3, 4, 5}};
cout << a << "\n\n" << v << endl;

View File

@ -0,0 +1,2 @@
Array<int, Dynamic, 1> v {{1, 2, 3, 4, 5}};
cout << v << endl;

View File

@ -0,0 +1,5 @@
MatrixXd m {
{1, 2, 3},
{4, 5, 6}
};
cout << m << endl;

View File

@ -1,6 +0,0 @@
Matrix<int, 2, 3> m {
{1, 2, 3},
{4, 5, 6}
};
VectorXi v {{1, 2}};
cout << m << "\n\n" << v << endl;

View File

@ -0,0 +1,2 @@
VectorXi v {{1, 2}};
cout << v << endl;