Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > tuples in C++11

Reply
Thread Tools

tuples in C++11

 
 
Single Stage to Orbit
Guest
Posts: n/a
 
      08-14-2012
Hello!

Suppose I have the following:

int main()
{
typedef boost::tuple<int, int, int> tuple3;
std::vector<tuple3> tuples;

tuples.push_back(tuple3(1, 2, 3));
tuples.push_back(tuple3(7, 8, 9));
tuples.push_back(tuple3(4, 5, 6));

for (auto& i : tuples)
std::cout << i.get<0>() << " " << i.get<1>() << " " <<
i.get<2>() << '\n';

return 0;
}

Is it even possible to have something like this:

for (auto& i : tuples)
{
for (unsigned j = 0; j < 3; ++j)
{
std::cout << i.get<j>();
if (j < 3)
std::cout << " ";
}

std::cout << '\n';
}

When I try it, GCC 4.6.3 says it's illegal to have an non constant
expression as in 'i.get<j>'. Are there any workarounds for this one?

Thanks!
--
Tactical Nuclear Kittens

 
Reply With Quote
 
 
 
 
Victor Bazarov
Guest
Posts: n/a
 
      08-14-2012
On 8/14/2012 2:17 PM, Single Stage to Orbit wrote:
> Suppose I have the following:
>
> int main()
> {
> typedef boost::tuple<int, int, int> tuple3;
> std::vector<tuple3> tuples;
>
> tuples.push_back(tuple3(1, 2, 3));
> tuples.push_back(tuple3(7, 8, 9));
> tuples.push_back(tuple3(4, 5, 6));
>
> for (auto& i : tuples)
> std::cout << i.get<0>() << " " << i.get<1>() << " " <<
> i.get<2>() << '\n';
>
> return 0;
> }
>
> Is it even possible to have something like this:
>
> for (auto& i : tuples)
> {
> for (unsigned j = 0; j < 3; ++j)
> {
> std::cout << i.get<j>();
> if (j < 3)
> std::cout << " ";
> }
>
> std::cout << '\n';
> }
>
> When I try it, GCC 4.6.3 says it's illegal to have an non constant
> expression as in 'i.get<j>'. Are there any workarounds for this one?


No, there are no work-arounds. But this really have nothing to do with
tuples or C++ 11.

You will get the same/similar error in this code:

#include <iostream>

template<int i> int foo() { return i*42; }

int main() {
for (int j = 0; j < 3; ++j)
std::cout << foo<j>() << std::endl;
}

The template argument for 'foo' can only be a const expression. A
run-time expression ('j') cannot be used.

You *could* write an adapter function, something like

template<class Tup> int Tget(Tup const& tup, int j)
{
switch (j)
{
case 0: return tup.get<0>();
case 1: return tup.get<1>();
....
}

and then use it

std::cout << Tget(i, j) << ...

but that kind of defeats the purpose, doesn't it?

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
 
 
 
Marcel Müller
Guest
Posts: n/a
 
      08-14-2012
On 14.08.2012 20:17, Single Stage to Orbit wrote:
> Is it even possible to have something like this:
>
> for (auto& i : tuples)
> {
> for (unsigned j = 0; j< 3; ++j)
> {
> std::cout<< i.get<j>();
> if (j< 3)
> std::cout<< " ";
> }
>
> std::cout<< '\n';
> }
>
> When I try it, GCC 4.6.3 says it's illegal to have an non constant
> expression as in 'i.get<j>'. Are there any workarounds for this one?


No, this is not possible. The compiler cannot know, which function to
call, because at the compile time j does not have a value. In fact you
want to call /another/ function at each loop iteration.
Furthermore i.get<0> and i.get<1> do not have the same type in general.
So the compiler cannot know the type of the expression get<j>.

Your code requires run time polymorphism rather than compile time
polymorphism.


If you want to iterate over the components of your tuple and if all
components have the same type then tuple<> is not the solution. This is
a vector (in the mathematical sense). The C++ equivalent of a vector
with a constant length is simply int[3]. I.e.:

typedef int tuple3[3];
....
tuples.push_back(tuple3({1, 2, 3}));
....
std::cout<< i[j];

(untested)


tuple<> is more something like an anonymous structure.


Marcel
 
Reply With Quote
 
Single Stage to Orbit
Guest
Posts: n/a
 
      08-14-2012
On Tue, 2012-08-14 at 14:33 -0400, Victor Bazarov wrote:
> On 8/14/2012 2:17 PM, Single Stage to Orbit wrote:
> > Suppose I have the following:


[ snip ]

> The template argument for 'foo' can only be a const expression. A
> run-time expression ('j') cannot be used.


OK, not possible.

> You *could* write an adapter function, something like
>
> template<class Tup> int Tget(Tup const& tup, int j)
> {
> switch (j)
> {
> case 0: return tup.get<0>();
> case 1: return tup.get<1>();
> ....
> }
>


[ snip ]

> but that kind of defeats the purpose, doesn't it?


Bit of a hack but yes you're quite right. Thanks.
--
Tactical Nuclear Kittens


 
Reply With Quote
 
Single Stage to Orbit
Guest
Posts: n/a
 
      08-14-2012
On Tue, 2012-08-14 at 20:43 +0200, Marcel Müller wrote:

[ snip ]

> No, this is not possible. The compiler cannot know, which function to
> call, because at the compile time j does not have a value. In fact

you
> want to call /another/ function at each loop iteration.
> Furthermore i.get<0> and i.get<1> do not have the same type in

general.
> So the compiler cannot know the type of the expression get<j>.
>
> Your code requires run time polymorphism rather than compile time
> polymorphism.


Right, I see.

> If you want to iterate over the components of your tuple and if all
> components have the same type then tuple<> is not the solution. This

is
> a vector (in the mathematical sense). The C++ equivalent of a vector
> with a constant length is simply int[3]. I.e.:


They won't all be the same types eventually - it was just an experiment
to see what I can do with tuples using the index into the tuple to
retrieve things.

I could use constants to get at the fields in the tuple, I suppose.
--
Tactical Nuclear Kittens


 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      08-14-2012
On 8/14/2012 3:15 PM, Single Stage to Orbit wrote:
> On Tue, 2012-08-14 at 20:43 +0200, Marcel Müller wrote:
>
> [ snip ]
>
>> No, this is not possible. The compiler cannot know, which function to
>> call, because at the compile time j does not have a value. In fact

> you
>> want to call /another/ function at each loop iteration.
>> Furthermore i.get<0> and i.get<1> do not have the same type in

> general.
>> So the compiler cannot know the type of the expression get<j>.
>>
>> Your code requires run time polymorphism rather than compile time
>> polymorphism.

>
> Right, I see.
>
>> If you want to iterate over the components of your tuple and if all
>> components have the same type then tuple<> is not the solution. This

> is
>> a vector (in the mathematical sense). The C++ equivalent of a vector
>> with a constant length is simply int[3]. I.e.:

>
> They won't all be the same types eventually - it was just an experiment
> to see what I can do with tuples using the index into the tuple to
> retrieve things.


If they are going to be different types, a function like I suggested
won't work (they need to be of the same type - the return value type of
that function, of course).

V
--
I do not respond to top-posted replies, please don't ask
 
Reply With Quote
 
88888 Dihedral
Guest
Posts: n/a
 
      08-14-2012
Single Stage to Orbit於 2012年8月15日星期三UTC+8上午2時17分26秒 寫道:
> Hello!
>
>
>
> Suppose I have the following:
>
>
>
> int main()
>
> {
>
> typedef boost::tuple<int, int, int> tuple3;
>
> std::vector<tuple3> tuples;
>
>
>
> tuples.push_back(tuple3(1, 2, 3));
>
> tuples.push_back(tuple3(7, 8, 9));
>
> tuples.push_back(tuple3(4, 5, 6));
>
>
>
> for (auto& i : tuples)
>
> std::cout << i.get<0>() << " " << i.get<1>() << " " <<
>
> i.get<2>() << '\n';
>
>
>
> return 0;
>
> }
>
>
>
> Is it even possible to have something like this:
>
>
>
> for (auto& i : tuples)
>
> {
>
> for (unsigned j = 0; j < 3; ++j)
>
> {
>
> std::cout << i.get<j>();
>
> if (j < 3)
>
> std::cout << " ";
>
> }
>
>
>
> std::cout << '\n';
>
> }
>
>
>
> When I try it, GCC 4.6.3 says it's illegal to have an non constant
>
> expression as in 'i.get<j>'. Are there any workarounds for this one?
>
>
>
> Thanks!
>
> --
>
> Tactical Nuclear Kittens




Single Stage to Orbit於 2012年8月15日星期三UTC+8上午2時17分26秒 寫道:
> Hello!
>
>
>
> Suppose I have the following:
>
>
>
> int main()
>
> {
>
> typedef boost::tuple<int, int, int> tuple3;
>
> std::vector<tuple3> tuples;
>
>
>
> tuples.push_back(tuple3(1, 2, 3));
>
> tuples.push_back(tuple3(7, 8, 9));
>
> tuples.push_back(tuple3(4, 5, 6));
>
>
>
> for (auto& i : tuples)
>
> std::cout << i.get<0>() << " " << i.get<1>() << " " <<
>
> i.get<2>() << '\n';
>
>
>
> return 0;
>
> }
>
>
>
> Is it even possible to have something like this:
>
>
>
> for (auto& i : tuples)
>
> {
>
> for (unsigned j = 0; j < 3; ++j)
>
> {
>
> std::cout << i.get<j>();
>
> if (j < 3)
>
> std::cout << " ";
>
> }
>
>
>
> std::cout << '\n';
>
> }
>
>
>
> When I try it, GCC 4.6.3 says it's illegal to have an non constant
>
> expression as in 'i.get<j>'. Are there any workarounds for this one?
>
>
>
> Thanks!
>
> --
>
> Tactical Nuclear Kittens


Do you plan to compress imutable objects into a serializable frozen file in
the hard disk or your own heap manager?

If you are not planning to do that then I don't think immutable tuples
are very helpful.
 
Reply With Quote
 
Single Stage to Orbit
Guest
Posts: n/a
 
      08-14-2012
On Tue, 2012-08-14 at 13:43 -0700, 88888 Dihedral wrote:
> Do you plan to compress imutable objects into a serializable frozen
> file in the hard disk or your own heap manager?
>
> If you are not planning to do that then I don't think immutable tuples
> are very helpful.


That's a bit advanced. Right now I'm just playing with the various
features of the C++11 language. Some I really like, like the new 'for
(auto& item : items)' syntax.
--
Tactical Nuclear Kittens

 
Reply With Quote
 
Single Stage to Orbit
Guest
Posts: n/a
 
      08-14-2012
On Tue, 2012-08-14 at 16:39 -0400, Victor Bazarov wrote:
> > They won't all be the same types eventually - it was just an

> experiment
> > to see what I can do with tuples using the index into the tuple to
> > retrieve things.

>
> If they are going to be different types, a function like I suggested
> won't work (they need to be of the same type - the return value type
> of that function, of course).


Indeed no, I realise that. Perhaps a template specialization will solve
that particular problem for me.
--
Tactical Nuclear Kittens

 
Reply With Quote
 
Marc
Guest
Posts: n/a
 
      08-14-2012
Marcel Mller wrote:

> If you want to iterate over the components of your tuple and if all
> components have the same type then tuple<> is not the solution. This is
> a vector (in the mathematical sense). The C++ equivalent of a vector
> with a constant length is simply int[3]. I.e.:


std::array<int,3> please, since the context is C++11...

> typedef int tuple3[3];
> ...
> tuples.push_back(tuple3({1, 2, 3}));
> ...
> std::cout<< i[j];
>
> (untested)


Indeed, doesn't compile.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Dictionaries with tuples or tuples of tuples Jon Reyes Python 18 02-19-2013 03:56 AM
Passing tuples of tuples to sqlite xera121 Python 8 09-30-2009 05:45 AM
tuples within tuples korovev76@gmail.com Python 12 10-27-2007 08:16 PM
Different tuples to one container? (One type of a pointer to point to different kinds of tuples?) fff_afafaf@yahoo.com C++ 5 10-05-2006 11:17 PM
xquery question.. how 2 if possible get tuples that have any attributes or elements of a given value Jeff Kish XML 11 10-21-2004 01:56 AM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57