Hansi | 20 May 11:59
Picon

tuple type question

Hello,

at the moment I want to make a getter function for a tuple type. The 
tuple is internally hidden in a class. For that I want to make a 
function which returns the values inside the tuple. The best solution 
would be if I can make a enum which defines the position inside the 
tuple and a template function which returns the value for this tuple.

I have tested the following, but it doesn't work:

typedef struct Members
		{
			enum Member
			{
				name = 0,
				value = 1,
			};
		}Members;

		template<enum Member member>
		element<0, Properties::Property>::type name()(const 
boost::tuples::tuple<std::wstring, boost::any>& prop)
		{
			return boost::tuples::get<member>(prop);
		}

Can anyone give my an hint? I'm not very familiar with the 
metaprogramming things...

Best regards
(Continue reading)

Noah Roberts | 20 May 18:43
Picon

Re: tuple type question

Hansi wrote:
> Hello,
> 
> at the moment I want to make a getter function for a tuple type. The 
> tuple is internally hidden in a class. For that I want to make a 
> function which returns the values inside the tuple. The best solution 
> would be if I can make a enum which defines the position inside the 
> tuple and a template function which returns the value for this tuple.
> 
> I have tested the following, but it doesn't work:
> 
> typedef struct Members
> 		{
> 			enum Member
> 			{
> 				name = 0,
> 				value = 1,
> 			};
> 		}Members;
> 
> 		template<enum Member member>
> 		element<0, Properties::Property>::type name()(const 
> boost::tuples::tuple<std::wstring, boost::any>& prop)
> 		{
> 			return boost::tuples::get<member>(prop);
> 		}

I didn't quite understand your goals here so I implemented both I 
thought you could mean:

(Continue reading)

Hansi | 21 May 08:42
Picon

Re: tuple type question


Noah Roberts schrieb:
> Hansi wrote:
>> Hello,
>>
>> at the moment I want to make a getter function for a tuple type. The 
>> tuple is internally hidden in a class. For that I want to make a 
>> function which returns the values inside the tuple. The best solution 
>> would be if I can make a enum which defines the position inside the 
>> tuple and a template function which returns the value for this tuple.
>>
>> I have tested the following, but it doesn't work:
>>
>> typedef struct Members
>> 		{
>> 			enum Member
>> 			{
>> 				name = 0,
>> 				value = 1,
>> 			};
>> 		}Members;
>>
>> 		template<enum Member member>
>> 		element<0, Properties::Property>::type name()(const 
>> boost::tuples::tuple<std::wstring, boost::any>& prop)
>> 		{
>> 			return boost::tuples::get<member>(prop);
>> 		}
> 
> I didn't quite understand your goals here so I implemented both I 
(Continue reading)

Daniel Krügler | 21 May 09:07
Picon
Favicon

Re: tuple type question

Hansi wrote:
> 
> Noah Roberts schrieb:
> 
>>Hansi wrote:
>>
>>>Hello,
>>>
>>>at the moment I want to make a getter function for a tuple type. The 
>>>tuple is internally hidden in a class. For that I want to make a 
>>>function which returns the values inside the tuple. The best solution 
>>>would be if I can make a enum which defines the position inside the 
>>>tuple and a template function which returns the value for this tuple.
>>>
>>>I have tested the following, but it doesn't work:
>>>
>>>typedef struct Members
>>>		{
>>>			enum Member
>>>			{
>>>				name = 0,
>>>				value = 1,
>>>			};
>>>		}Members;
>>>
>>>		template<enum Member member>
>>>		element<0, Properties::Property>::type name()(const 
>>>boost::tuples::tuple<std::wstring, boost::any>& prop)
>>>		{
>>>			return boost::tuples::get<member>(prop);
(Continue reading)

Maik Beckmann | 21 May 09:53

Re: tuple type question

Am Mittwoch 21 Mai 2008 08:42:34 schrieb Hansi:
> Noah Roberts schrieb:
> > #include <boost/tuple/tuple.hpp>
> > #include <string>
> > #include <iostream>
> >
> > template < typename T1, typename T2 >
> > struct Test
> > {
> >    typedef boost::tuple<T1,T2> tuple_t;
> >    tuple_t tup;
> >
> >    enum Members { NAME, VALUE };
> >
> >    typename boost::tuples::element<NAME, tuple_t>::type name() { return
> > tup.get<NAME>(); }

This code is almost correct :o) .  Try the attached File.

> this version doesn't work with my compiler (msvc8.0). I get the error:
>
> error C2899:typename cannot be used outside a template declaration
>
> But this would be the preferred version for me. Have you an idea how I
> can solve this?

Best,
 -- Maik

(Continue reading)

Igor R. | 21 May 09:57
Picon
Favicon

Re: tuple type question

> This code is almost correct :o) . Try the attached File.

Now you missed one "typename": template < Members mem >
 

Get news, entertainment and everything you care about at Live.com. Check it out!
_______________________________________________
Boost-users mailing list
Boost-users <at> lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Maik Beckmann | 21 May 10:06

Re: tuple type question

Am Mittwoch 21 Mai 2008 09:57:10 schrieb Igor R.:
> > This code is almost correct :o) . Try the attached File.
>
> Now you missed one "typename": template < Members mem >

??

Please state the complete statement you refer to.

-- Maik
Igor R. | 21 May 10:12
Picon
Favicon

Re: tuple type question

Sorry, I just didn't read the code correctly.
 
> > > This code is almost correct :o) . Try the attached File.
> >
> > Now you missed one "typename": template < Members mem >
>
> ??
>
> Please state the complete statement you refer to.
>
> -- Maik


Invite your mail contacts to join your friends list with Windows Live Spaces. It's easy! Try it!
_______________________________________________
Boost-users mailing list
Boost-users <at> lists.boost.org
http://lists.boost.org/mailman/listinfo.cgi/boost-users
Maik Beckmann | 21 May 10:18

Re: tuple type question

Am Mittwoch 21 Mai 2008 10:12:50 schrieb Igor R.:
> Sorry, I just didn't read the code correctly.

I try always to send only code which ran trough a compiler, as I did in this 
case :o) 
Hansi | 21 May 10:55
Picon

Re: tuple type question

Okay this version is working.
The problem is that I have a fixed defined tuple and for that the tuple 
is not defined inside a template struct.
for that I get the error that typename can be used only inside a 
template declaration...
I have something similar to the following declaration:

struct Test
{
     typedef boost::tuple<int,char> tuple_t;
     tuple_t tup;
     enum Members { NAME, VALUE };

     typename boost::tuples::element<NAME, tuple_t>::type
     name()
     { return boost::get<NAME>(tup); }

     template < Members mem >
     typename boost::tuples::element<mem, tuple_t>::type
     member()
     { return boost::get<mem>(tup); }
};

Maik Beckmann schrieb:
> Am Mittwoch 21 Mai 2008 08:42:34 schrieb Hansi:
>> Noah Roberts schrieb:
>>> #include <boost/tuple/tuple.hpp>
>>> #include <string>
>>> #include <iostream>
>>>
>>> template < typename T1, typename T2 >
>>> struct Test
>>> {
>>>    typedef boost::tuple<T1,T2> tuple_t;
>>>    tuple_t tup;
>>>
>>>    enum Members { NAME, VALUE };
>>>
>>>    typename boost::tuples::element<NAME, tuple_t>::type name() { return
>>> tup.get<NAME>(); }
> 
> This code is almost correct :o) .  Try the attached File.
> 
>> this version doesn't work with my compiler (msvc8.0). I get the error:
>>
>> error C2899:typename cannot be used outside a template declaration
>>
>> But this would be the preferred version for me. Have you an idea how I
>> can solve this?
> 
> 
> Best,
>  -- Maik
> 
> 
> 
> 
> 
> 
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Boost-users mailing list
> Boost-users <at> lists.boost.org
> http://lists.boost.org/mailman/listinfo.cgi/boost-users
Maik Beckmann | 21 May 11:13

Re: tuple type question

Am Mittwoch 21 Mai 2008 10:55:53 schrieb Hansi:
> Okay this version is working.
> The problem is that I have a fixed defined tuple and for that the tuple
> is not defined inside a template struct.
> for that I get the error that typename can be used only inside a
> template declaration...

The compiler is right, omit the typename keyword if you're not inside a 
template.  In this case you can even write
  tup.get<enumFoo>()
instead of
  tup.template get<enumFoo>()

The good thing about this syntax
  get<Whatever>(tup)
is, it work always, inside a template or not.

-- Maik
Noah Roberts | 21 May 18:22
Picon

Re: tuple type question

Maik Beckmann wrote:
> Am Mittwoch 21 Mai 2008 10:55:53 schrieb Hansi:
>> Okay this version is working.
>> The problem is that I have a fixed defined tuple and for that the tuple
>> is not defined inside a template struct.
>> for that I get the error that typename can be used only inside a
>> template declaration...
> 
> The compiler is right, omit the typename keyword if you're not inside a 
> template.  In this case you can even write
>   tup.get<enumFoo>()
> instead of
>   tup.template get<enumFoo>()

Should I have had that in my function?  The compiler didn't bitch about 
it not being there...

I also test my code before posting to lists and such unless otherwise 
expressed.  The code I originally posted compiled and worked just fine. 
  Can you cite chapter and verse why it shouldn't have?  I try to be as 
standard compliant as I can.
Michael Fawcett | 21 May 18:41
Picon

Re: tuple type question

On Wed, May 21, 2008 at 12:22 PM, Noah Roberts <roberts.noah <at> gmail.com> wrote:
> Maik Beckmann wrote:
>>
>> The compiler is right, omit the typename keyword if you're not inside a
>> template.  In this case you can even write
>>   tup.get<enumFoo>()
>> instead of
>>   tup.template get<enumFoo>()
>
> Should I have had that in my function?  The compiler didn't bitch about
> it not being there...
>
> I also test my code before posting to lists and such unless otherwise
> expressed.  The code I originally posted compiled and worked just fine.
>  Can you cite chapter and verse why it shouldn't have?  I try to be as
> standard compliant as I can.

http://www.comeaucomputing.com/techtalk/templates/#templateprefix

--Michael Fawcett
Noah Roberts | 21 May 18:17
Picon

Re: tuple type question

Hansi wrote:
> 
> Noah Roberts schrieb:
>> Hansi wrote:
>>> Hello,
>>>
>>> at the moment I want to make a getter function for a tuple type. The 
>>> tuple is internally hidden in a class. For that I want to make a 
>>> function which returns the values inside the tuple. The best solution 
>>> would be if I can make a enum which defines the position inside the 
>>> tuple and a template function which returns the value for this tuple.
>>>
>>> I have tested the following, but it doesn't work:
>>>
>>> typedef struct Members
>>> 		{
>>> 			enum Member
>>> 			{
>>> 				name = 0,
>>> 				value = 1,
>>> 			};
>>> 		}Members;
>>>
>>> 		template<enum Member member>
>>> 		element<0, Properties::Property>::type name()(const 
>>> boost::tuples::tuple<std::wstring, boost::any>& prop)
>>> 		{
>>> 			return boost::tuples::get<member>(prop);
>>> 		}
>> I didn't quite understand your goals here so I implemented both I 
>> thought you could mean:
>>
>>
>> #include <boost/tuple/tuple.hpp>
>> #include <string>
>> #include <iostream>
>>
>> template < typename T1, typename T2 >
>> struct Test
>> {
>>    typedef boost::tuple<T1,T2> tuple_t;
>>    tuple_t tup;
>>
>>    enum Members { NAME, VALUE };
>>
>>    typename boost::tuples::element<NAME, tuple_t>::type name() { return 
>> tup.get<NAME>(); }
> 
> this version doesn't work with my compiler (msvc8.0). I get the error:
> 
> error C2899:typename cannot be used outside a template declaration
> 
> But this would be the preferred version for me. Have you an idea how I 
> can solve this?

That's exactly the compiler I used to compile this code.  Have you 
altered it in some way?  The typename keyword is quite specifically 
needed in the above code, but would be quite specifically disallowed 
with some minor differences, namely if the "Test" class was not 
templated or if the tuple type was not dependent on any of the template 
parameters.

Try to just create a new project and copy/paste my code into it, 
replacing their non-standard main function with the one I have.  You'll 
probably need to keep the "stdafx.h" include.

What version of boost?  I have 1.34 on this system; we have not upgraded 
yet as our products will adversely affected by changes to some libraries 
and we're not yet prepared to deal with that.

I have a feeling though that you tried to integrate my code into your 
particular problem without first testing mine.  You may very well not 
need the 'typename' keyword.  I would suggest really studying when and 
where to use that keyword if that's the case for it is fundamental to 
understanding templates and is not the easiest thing in the world to learn.
Hansi | 21 May 21:26
Picon

Re: tuple type question

Hello,

Thank you for your helped.
You was right. I have tested your code inside mine. For that I have 
adapted something and the problem (I have posted it in another answer).
The problem ist that I had the follwing struct:

struct Test
{
      typedef boost::tuple<int,char> tuple_t;
      tuple_t tup;
      enum Members { NAME, VALUE };

      typename boost::tuples::element<NAME, tuple_t>::type
      name()
      { return boost::get<NAME>(tup); }
};

and here the declaration doesn't work.

I use boost 1.34.1

Thank you very much
Hansjörg

Noah Roberts schrieb:
> Hansi wrote:
>> Noah Roberts schrieb:
>>> Hansi wrote:
>>>> Hello,
>>>>
>>>> at the moment I want to make a getter function for a tuple type. The 
>>>> tuple is internally hidden in a class. For that I want to make a 
>>>> function which returns the values inside the tuple. The best solution 
>>>> would be if I can make a enum which defines the position inside the 
>>>> tuple and a template function which returns the value for this tuple.
>>>>
>>>> I have tested the following, but it doesn't work:
>>>>
>>>> typedef struct Members
>>>> 		{
>>>> 			enum Member
>>>> 			{
>>>> 				name = 0,
>>>> 				value = 1,
>>>> 			};
>>>> 		}Members;
>>>>
>>>> 		template<enum Member member>
>>>> 		element<0, Properties::Property>::type name()(const 
>>>> boost::tuples::tuple<std::wstring, boost::any>& prop)
>>>> 		{
>>>> 			return boost::tuples::get<member>(prop);
>>>> 		}
>>> I didn't quite understand your goals here so I implemented both I 
>>> thought you could mean:
>>>
>>>
>>> #include <boost/tuple/tuple.hpp>
>>> #include <string>
>>> #include <iostream>
>>>
>>> template < typename T1, typename T2 >
>>> struct Test
>>> {
>>>    typedef boost::tuple<T1,T2> tuple_t;
>>>    tuple_t tup;
>>>
>>>    enum Members { NAME, VALUE };
>>>
>>>    typename boost::tuples::element<NAME, tuple_t>::type name() { return 
>>> tup.get<NAME>(); }
>> this version doesn't work with my compiler (msvc8.0). I get the error:
>>
>> error C2899:typename cannot be used outside a template declaration
>>
>> But this would be the preferred version for me. Have you an idea how I 
>> can solve this?
> 
> That's exactly the compiler I used to compile this code.  Have you 
> altered it in some way?  The typename keyword is quite specifically 
> needed in the above code, but would be quite specifically disallowed 
> with some minor differences, namely if the "Test" class was not 
> templated or if the tuple type was not dependent on any of the template 
> parameters.
> 
> Try to just create a new project and copy/paste my code into it, 
> replacing their non-standard main function with the one I have.  You'll 
> probably need to keep the "stdafx.h" include.
> 
> What version of boost?  I have 1.34 on this system; we have not upgraded 
> yet as our products will adversely affected by changes to some libraries 
> and we're not yet prepared to deal with that.
> 
> I have a feeling though that you tried to integrate my code into your 
> particular problem without first testing mine.  You may very well not 
> need the 'typename' keyword.  I would suggest really studying when and 
> where to use that keyword if that's the case for it is fundamental to 
> understanding templates and is not the easiest thing in the world to learn.
Noah Roberts | 21 May 22:16
Picon

Re: tuple type question

Hansi wrote:
> Hello,
> 
> Thank you for your helped.
> You was right. I have tested your code inside mine. For that I have 
> adapted something and the problem (I have posted it in another answer).
> The problem ist that I had the follwing struct:
> 
> struct Test
> {
>       typedef boost::tuple<int,char> tuple_t;
>       tuple_t tup;
>       enum Members { NAME, VALUE };
> 
>       typename boost::tuples::element<NAME, tuple_t>::type
>       name()
>       { return boost::get<NAME>(tup); }
> };
> 
> and here the declaration doesn't work.

loose the typename.  I read what others stated about its appropriateness 
and I don't know if that is true or not.  What I do know is that the 
compiler we both use won't accept it.

If you remove typename it should work.
Daniel Krügler | 22 May 08:29
Picon
Favicon

Re: tuple type question

Noah Roberts wrote:
> Hansi wrote:
> 
>>Hello,
>>
>>Thank you for your helped.
>>You was right. I have tested your code inside mine. For that I have 
>>adapted something and the problem (I have posted it in another answer).
>>The problem ist that I had the follwing struct:
>>
>>struct Test
>>{
>>      typedef boost::tuple<int,char> tuple_t;
>>      tuple_t tup;
>>      enum Members { NAME, VALUE };
>>
>>      typename boost::tuples::element<NAME, tuple_t>::type
>>      name()
>>      { return boost::get<NAME>(tup); }
>>};
>>
>>and here the declaration doesn't work.
> 
> 
> loose the typename.  I read what others stated about its appropriateness 
> and I don't know if that is true or not.  What I do know is that the 
> compiler we both use won't accept it.
> 
> If you remove typename it should work.

I totally agree with you, the typename here - at least what is
visible from this snippet context - is not legal according
to C++03, see [temp.res], 5:

"The keyword typename shall only be used in template declarations
and definitions, including in the return type of a function template
or member function template, in the return type for the definition
of a member function of a class template or of a class nested within
a class template, and in the type-specifier for the definition
of a static member of a class template or of a class nested within
a class template."

Concerning the opinion of others: My original reply
suggesting that the compiler is broken was related to
a different code, which started with a template context
like this:

template < typename T1, typename T2 >
struct Test {
   typedef boost::tuple<T1,T2> tuple_t;
   tuple_t tup;

   enum Members { NAME, VALUE };
   typename boost::tuples::element<NAME, tuple_t>::type name() {
     ...
   }
};

The typename in front of boost::tuples::element is legal
and it is *required* in this case. My original posting
overlooked that the arguments of the relevant template
were dependent, but the answer was still correct, because
the important point is that the typename is legal in a
template context, even if the corresponding name is *not*
dependent. So this example is legal as well:

#include <utility>

template <typename>
struct TT {
   typename std::pair<int, double>::first_type name() {
     return 0;
   }
};

int main() {
   return TT<void>().name();
}

If the compiler does not accept the typename here, it is
broken, which was the essence of my OP.

Greetings from Bremen,

Daniel Krügler
Noah Roberts | 22 May 17:47
Picon

Re: tuple type question

Daniel Krügler wrote:

> #include <utility>
> 
> template <typename>
> struct TT {
>    typename std::pair<int, double>::first_type name() {
>      return 0;
>    }
> };
> 
> int main() {
>    return TT<void>().name();
> }
> 
> If the compiler does not accept the typename here, it is
> broken, which was the essence of my OP.

I see.  Yeah, it was a bit hard to track what was going on with the OP's 
code.
Hansi | 22 May 10:28
Picon

Re: tuple type question

Yes this works! thanks

Noah Roberts schrieb:
> Hansi wrote:
>> Hello,
>>
>> Thank you for your helped.
>> You was right. I have tested your code inside mine. For that I have 
>> adapted something and the problem (I have posted it in another answer).
>> The problem ist that I had the follwing struct:
>>
>> struct Test
>> {
>>       typedef boost::tuple<int,char> tuple_t;
>>       tuple_t tup;
>>       enum Members { NAME, VALUE };
>>
>>       typename boost::tuples::element<NAME, tuple_t>::type
>>       name()
>>       { return boost::get<NAME>(tup); }
>> };
>>
>> and here the declaration doesn't work.
> 
> loose the typename.  I read what others stated about its appropriateness 
> and I don't know if that is true or not.  What I do know is that the 
> compiler we both use won't accept it.
> 
> If you remove typename it should work.
Olaf Peter | 22 May 19:42
Picon
Picon

Re: tuple type question

Hi,

> struct Test
> {
>       typedef boost::tuple<int,char> tuple_t;
>       tuple_t tup;
>       enum Members { NAME, VALUE };
> 
>       typename boost::tuples::element<NAME, tuple_t>::type
>       name()
>       { return boost::get<NAME>(tup); }
> };

why not simple derive:

struct Test
   : boost::tuple<int,char>
{
       enum Members { NAME, VALUE };
};

Than you have the tuple calling syntax:

get<Test::Name>( ... )

That's what I use for reading and writing "named" tuples.

Regards,
Olaf
Noah Roberts | 23 May 00:13
Picon

Re: tuple type question

Olaf Peter wrote:

> why not simple derive:
> 
> struct Test
>    : boost::tuple<int,char>
> {
>        enum Members { NAME, VALUE };
> };
> 
> Than you have the tuple calling syntax:
> 
> get<Test::Name>( ... )
> 
> That's what I use for reading and writing "named" tuples.

How useful have people found this technique?  I started using tuples for 
simple data structures and did such a thing.  I found that it added more 
syntatic complexity than was of benefit; that simply creating a data 
store class/POD was the easier, clearer method.
Maik Beckmann | 21 May 09:46

Re: tuple type question

Am Dienstag 20 Mai 2008 18:43:28 schrieb Noah Roberts:

> tup.get<NAME>(); 

> tup.get<mem>(); 

Did you mean
  boost::get<NAME>(tup); 
  boost::get<mem>(tup); 
??

-- Maik
Hansi | 21 May 09:49
Picon

Re: tuple type question

I mean the version
tup.get<NAME>();

Regarding to microsoft

The typename keyword can be used only in a template definition or 
declaration. In a template declaration, it can be used in two ways:

// C2899b.cpp
// compile with: /c
struct Y {
    typedef int B;
    typename Y::B b;   // C2899
};

Best regards
Hansjörg

Maik Beckmann schrieb:
> Am Dienstag 20 Mai 2008 18:43:28 schrieb Noah Roberts:
> 
>> tup.get<NAME>(); 
> 
>> tup.get<mem>(); 
> 
> Did you mean
>   boost::get<NAME>(tup); 
>   boost::get<mem>(tup); 
> ??
> 
> 
> -- Maik
Maik Beckmann | 21 May 10:04

Re: tuple type question

Am Mittwoch 21 Mai 2008 09:49:09 schrieb Hansi:
> I mean the version
> tup.get<NAME>();

Ahh, since your are inside a template class you have to write
  tup.template get<NAME>();

HTH,
 -- Maik

Gmane