Thank you for developing the really nice library! It would be great to add `value_type` nested-type to `EigenBase` template<typename Derived> struct EigenBase { typedef typename internal::traits<Derived>::Scalar value_type; // ... } since this improves the interoperability of Eigen in generic programming. (For example, vectors/matrices in Boost.uBLAS have `value_type` nested-type.)
Honestly I would not see very much use-cases for that. If you need this, you can write your own traits: template<class T> struct value_type_traits { typedef typename T::value_type type; }; with the specialization: template<class Derived> struct value_type_traits<Eigen::EigenBase<Derived> > { typedef typename Eigen::EigenBase<Derived>::Scalar type; }; (Not tested ...)
I often use `typename T::value_type` to make a local variable in generic functions. We can use `value_type_traits<Eigen::EigenBase<Eigen::Vector3f> >`, but we cannot use `value_type_traits<Eigen::Vector3f>`. So we cannot pass an instance of`Eigen::Vector3f` to the following function template: template <typename T> void f(T const& t) { typename value_type_traits<T>::type val; } (We can make the above code work fine by writing partial specializations for all the template classes, such as `Eigen::Matrix`, `Eigen::SparseMatrix`, `Eigen::Diagonal`, etc. But I don't want to do this…)
Ok, the solution I suggested does not work, but it is possible with some additional work: http://stackoverflow.com/questions/281725/template-specialization-based-on-inherit-class An alternative, implementing your suggestion on a user level, would be extending MatrixBase as suggested here: http://eigen.tuxfamily.org/api/TopicCustomizingEigen.html#ExtendingMatrixBase
Yep, and Boost.TypeTraits has is_base_of. I should admit that my use case is too weak to add value_type nested-type. Thanks for your help and for your time, Christoph!
Just for the record: Without compiler support (i.e. type traits intrinsics) of `is_base_of`, C++03 implementation of `is_base_of` cannot be used to determine whether the type is derived from EigenBase. This is because `is_base_of<EigenBase<Derived>, Derived>` instantiates `EigenBase<Derived>` and it causes error if `Derived` is not an Eigen object. In C++11, `is_base_of<EigenBase<Derived>, Derived>` is guaranteed not to instantiate `EigenBase<Derived>`. So it is safe to use template <typename T> struct is_eigen_object : std::is_base_of<Eigen::EigenBase<T>, T> {}; for determining Eigen objects. Note that gcc had a bug in `std::is_base_of` until very recently. The bug was just fixed in gcc-4.7.0 20111015 (experimental) and we cannot use this solution on older gcc. As a C++03 solution, I use BOOST_MPL_HAS_XXX_TRAIT_DEF(Scalar) BOOST_MPL_HAS_XXX_TRAIT_DEF(Index) BOOST_MPL_HAS_XXX_TRAIT_DEF(StorageKind) template <typename T> struct is_eigen_object : boost::mpl::and_<has_Scalar<T>, has_Index<T>, has_StorageKind<T> > {}; for determining Eigen objects.
I'd like to reopen this issue. I've run into the same problem when trying to write generic code that works with both Eigen and STL lib types. Perhaps I'm not understanding the proposed solution, but it seems the suggestion is to not use direct eigen types but instead to derive types and only used the derived types with templates in question. If that is the suggestion it seems to somewhat defeat the purpose by making the generic code significantly less generic. I'm not sure how high STL compatibility is on the list, but IMHO, it's worth pursuing especially if the cost is as low as an extra typedef.
Created attachment 466 [details] SFINAE based workaround I'm still not convinced that we should add typedefs to achieve a limited std-library compatibility. I attached a (this time working) example how to work-around it using a SFINAE-based traits struct.
Another workaround is to use our "plugin" mechanism: http://eigen.tuxfamily.org/dox/TopicCustomizingEigen.html#title0 Actually, the same question might also be asked for STL compatible iterators (bug 231)
*** Bug 995 has been marked as a duplicate of this bug. ***
Bug 995 also asked for further typedefs, such as allocator_type, etc
>> It would be great to add `value_type` nested-type to `EigenBase` +1 > Honestly I would not see very much use-cases for that. I've always been able to query containers I use for the type they contain by doing T::value_type, except with Eigen. Admittedly I've mostly been using STL containers so far but I think they set a good example. Comment 1 suggested adding around 8 lines of code to every user program needing this but adding two lines to Eigen instead would reduce typing a lot in the long run. Standard containers also define a lot of other stuff for every container and at least size_type or difference_type would seem to make sense for Eigen Matrices. If the former was available I wouldn't have to guess whether size() returns a signed or unsigned integer, when looping over vector indices etc., with the accompanying compiler warnings until I change the type of loop variable to be the same as returned by e.g. Vector3d.size(). As for the SFINAE stuff mentioned e.g. in https://bitbucket.org/eigen/eigen/pull-request/111 , I'm not sure what that's about exactly but feels like overengineering to me. I'm guessing there's a good reason why all (most?) STL containers have those typedefs...
Is the reason for not including a typedef value_type the fact that it will break code which already works around the problem of not having a typedef value_type? I guess that makes sense. Although in this case the problem might be quite small because those who don't have a workaround won't notice and those who do will probably be happy to get rid of the workaround.
std-container compatibility was never a primary design goal of Eigen and Matrix is not really intended to be used as storage container. Mathematically, a Matrix is merely a representation of a linear function. However, the borders between a container and a Matrix (even more, an Array) are fuzzy and I'm not opposing this entirely anymore. Overall we are quite reluctant with adding things which we can hardly change afterwards -- and since none of us core developers felt great need for this, this was never pushed forward ... There is only little code inside Eigen which breaks when adding value_type (e.g., SparseMatrix::reserve), but that must be changed simultaneously, of course. An actual design decision is, e.g., what shall value_type be for Matrix::colwise()/Matrix::rowwise()? Especially, if we implement iterators as suggested in Bug 231 comment 10, something like a view to a vector would make more sense than Scalar. Perhaps, adding value_type to PlainObjectBase would be a solution that makes most people happy, while leaving us the decision what to do for other types. E.g., there are also types which do not allow coeff-wise access, providing a value_type there would hardly make sense.
Good idea to limit value_type to what looks like containers. This definitely sounds safer than making it an alias to Scalar thorough Eigen's expressions.
hm, after all, I cannot see any problem with making value_type an alias to Scalar for all "true" expressions, or in other words, I don't see cases where it could make sense to define it to something else. So defining it DenseBase/SparseMatrixBase seems to be safe. Note that, colwise/rowwise do not return a true expression, and the returned type does not even inherit EigenBase.
Created attachment 564 [details] patch adding value_type typedef
(In reply to Gael Guennebaud from comment #16) > Created attachment 564 [details] I'm ok with that patch.
https://bitbucket.org/eigen/eigen/commits/2a120c7a1519/ Changeset: 2a120c7a1519 User: ggael Date: 2015-04-24 07:44:24+00:00 Summary: Bug 360: add value_type typedef to DenseBase/SparseMatrixBase
-- GitLab Migration Automatic Message -- This bug has been migrated to gitlab.com's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.com/libeigen/eigen/issues/360.