This bugzilla service is closed. All entries have been migrated to
Bug 360 - Adding `value_type` nested-type to `EigenBase`
Summary: Adding `value_type` nested-type to `EigenBase`
Alias: None
Product: Eigen
Classification: Unclassified
Component: Core - general (show other bugs)
Version: 3.3 (current stable)
Hardware: All All
: Lowest Feature Request
Assignee: Nobody
: 995 (view as bug list)
Depends on:
Blocks: 231 329
  Show dependency treegraph
Reported: 2011-10-13 19:55 UTC by michel_morin
Modified: 2019-12-04 11:11 UTC (History)
5 users (show)

SFINAE based workaround (775 bytes, text/plain)
2014-06-15 03:50 UTC, Christoph Hertzberg
no flags Details
patch adding value_type typedef (5.40 KB, patch)
2015-04-21 08:51 UTC, Gael Guennebaud
no flags Details | Diff

Description michel_morin 2011-10-13 19:55:02 UTC
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.)
Comment 1 Christoph Hertzberg 2011-10-13 20:24:40 UTC
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 ...)
Comment 2 michel_morin 2011-10-13 21:00:23 UTC
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…)
Comment 3 Christoph Hertzberg 2011-10-14 00:43:16 UTC
Ok, the solution I suggested does not work, but it is possible with some additional work:

An alternative, implementing your suggestion on a user level, would be extending MatrixBase as suggested here:
Comment 4 michel_morin 2011-10-14 01:40:30 UTC
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!
Comment 5 michel_morin 2011-10-20 01:50:44 UTC
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
    template <typename T>
    struct is_eigen_object : boost::mpl::and_<has_Scalar<T>, has_Index<T>, has_StorageKind<T> >
for determining Eigen objects.
Comment 6 Andy Somerville 2012-04-12 22:18:28 UTC
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.
Comment 7 Christoph Hertzberg 2014-06-15 03:50:21 UTC
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.
Comment 8 Gael Guennebaud 2014-06-16 12:05:26 UTC
Another workaround is to use our "plugin" mechanism:

Actually, the same question might also be asked for STL compatible iterators (bug 231)
Comment 9 Christoph Hertzberg 2015-04-13 16:57:02 UTC
*** Bug 995 has been marked as a duplicate of this bug. ***
Comment 10 Christoph Hertzberg 2015-04-13 16:58:40 UTC
Bug 995 also asked for further typedefs, such as allocator_type, etc
Comment 11 Ilja Honkonen 2015-04-16 14:54:43 UTC
>> It would be great to add `value_type` nested-type to `EigenBase`


> 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 , 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...
Comment 12 Ilja Honkonen 2015-04-16 16:16:36 UTC
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.
Comment 13 Christoph Hertzberg 2015-04-16 19:20:40 UTC
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.
Comment 14 Gael Guennebaud 2015-04-16 20:45:13 UTC
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.
Comment 15 Gael Guennebaud 2015-04-21 08:42:32 UTC
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.
Comment 16 Gael Guennebaud 2015-04-21 08:51:42 UTC
Created attachment 564 [details]
patch adding value_type typedef
Comment 17 Christoph Hertzberg 2015-04-23 12:02:14 UTC
(In reply to Gael Guennebaud from comment #16)
> Created attachment 564 [details]
I'm ok with that patch.
Comment 18 Gael Guennebaud 2015-04-24 07:45:08 UTC
Changeset:   2a120c7a1519
User:        ggael
Date:        2015-04-24 07:44:24+00:00
Summary:     Bug 360: add value_type typedef to DenseBase/SparseMatrixBase
Comment 19 Nobody 2019-12-04 11:11:27 UTC
-- GitLab Migration Automatic Message --

This bug has been migrated to'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:

Note You need to log in before you can comment on or make changes to this bug.