Reputation:
If I have a struct s
:
template<typename T>
struct s {
std::vector<T> list;
};
Defined in main()
as:
s<long double> x;
And I try to get the type of list
's iterator using:
typedef typename std::vector<decltype(x.list[0])>::iterator IT;
GCC 7.2.1 produces a bunch of errors, beginning with:
/usr/include/c++/7/bits/alloc_traits.h:392:27: error: forming pointer to reference type 'long double&'
using pointer = _Tp*;
^
I doubt there is anything wrong with the underlying implementation of C++ in GCC, which this error seems to indicate.
Using this method also assumes that list
is not empty, so I instead tried using ::value_type
(as suggested on other SO answers):
typedef typename std::vector<x.list::value_type>::iterator IT;
GCC again produces errors:
error: the value of 'x' is not usable in a constant expression.
typedef typename std::vector<x.list::value_type>::iterator IT;
^~~~
In order to find an alternative, I added a type-holding variable to the struct:
template<typename T>
struct s {
T typeholder;
std::vector<T> list;
};
And this worked fine, using:
typedef typename std::vector<decltype(x.typeholder)>::iterator IT;
Where am I going wrong here? It seems convoluted to need to define an unused variable just to hold the type. Am I misusing ::value_type
?
Upvotes: 0
Views: 71
Reputation: 1678
The type of decltype(x.list[0])
is long double&
. std::vector
cannot store references, hence you get an error. The second error ("error: the value of 'x' is not usable in a constant expression.") also seems pretty obvious: you need a type instead of a value. This should compile without errors:
#include <vector>
template<typename T>
struct s {
std::vector<T> list;
};
int main()
{
s<long double> x;
typedef typename std::vector<decltype(x.list)::value_type>::iterator IT;
}
Upvotes: 1