Afternoon all,
The class template shown below contains two std::vectors of different types. These are both held in an embedded std::tuple so that we can have a templatized at<I>(j) element accessor that calls std::vector::at(j) through std::get<I>. I like this a lot better than having separate column0(j) and column1(j) accessors.
It works okay at first glance but fails if you try to convert the return value of at<I>(j) to a different type. Changing the access level of TwoVectors::TU to "public" does fix the problem, but that is really undesirable for this application.
I'm using G++ 4.7.3, and have found a related bug in that version that *might* be the cause of this:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=52816
However, I'm not sure whether the current problem is the same as the one addressed there, because it only seems to pop up where temporary objects are concerned.
I don't know much about rvalue references yet, and std::get can return those... could my use of decltype() be the problem here?
Anyways, here's the code.
Thanks
Grump
Code:
#include <vector>
#include <tuple>
// Template to hold two std::vectors of types T and U.
// These are contained in an embedded 2-tuple.
template <typename T, typename U>
class TwoVectors
{
// The 2-tuple is private to ensure that both vectors are the same length.
std::tuple< std::vector< T >,
std::vector< U > > TU;
public:
// Resizer.
void resize(int rows)
{
std::get<0>(TU).resize(rows);
std::get<1>(TU).resize(rows);
}
// Element accessor.
// This forwards to std::vector::at(i), via std::get<I>.
template <int I>
auto at(int i) -> decltype(std::get<I>(TU).at(i))
{
return std::get<I>(TU).at(i);
}
};
int main()
{
// Construct a TwoVectors object and set some element values.
// No problems with at<I>(i) occur here...
TwoVectors<int, float> tv;
tv.resize(2);
tv.at<0>(0) = 2;
tv.at<0>(1) = 4;
tv.at<1>(0) = 3.;
tv.at<1>(1) = 5.;
// ... or here...
float x = tv.at<1>(1);
// ... but this implodes at compile time.
double y = double(tv.at<1>(1));
/* The error message is:
Type2.C:13:34: error: ‘std::tuple< std::vector<int, std::allocator<int> >,
std::vector<float, std::allocator<float> >
>
TwoVectors<int, float>::TU’ is private
Type2.C:55:32: error: within this context
*/
}