typeof? How to in C++?

P

Paulo da Silva

Hi.

Why is this code not working? How can I implement this?
Thanks.


class C
{ private:
struct stat st;
....

public:
typeof(st.st_gid) gid() const {return st.st_gid;}
....
}
 
K

kwikius

Hi.

Why is this code not working? How can I implement this?
Thanks.

class C
{ private:
struct stat st;
...

public:
typeof(st.st_gid) gid() const {return st.st_gid;}
...



}- Hide quoted text -

for gcc use (IIRC) __typeof__ or something like that. There are also
cool hacks for VC7.1 and VC8, that trick the compiler into doing the
same ( probably other compilers too), but officially typeof is missing
from C++. It will be available in the next major c++ version, in form
of decltype and auto AFAIK.

regards
Andy Little
 
E

Emery

Hi.

Why is this code not working? How can I implement this?
Thanks.

class C
{ private:
struct stat st;
...

public:
typeof(st.st_gid) gid() const {return st.st_gid;}
...

}

What purpose could typeof serve that polymorphism doesn't?
 
P

Paulo da Silva

Emery escreveu:
What purpose could typeof serve that polymorphism doesn't?
The example is clear.
I need to use the stat structure without knowing its members types, i.e.
I am not sure if they are standard or system dependent. typeof fits
exactly my purposes. Somehow it works *only* for static declarations
(for g++ at least). So, I could turn around the problem by declaring a
"dummy" no space taker member:
static struct stat sttype[0];

Then I can write:

typeof(sttype[0].st_gid) gid() const {return st.st_gid;}

Any better solution?
Thanks.
 
R

Robert Bauck Hamar

Paulo said:
Emery escreveu:

What do you mean?
The example is clear.
I need to use the stat structure without knowing its members types, i.e.
I am not sure if they are standard or system dependent.

They are and are not standard.

They are not standard in that the C++ and C standards does not describe or
reference any struct stat.

They are standard in that POSIX describes them, and POSIX is a standard. The
which is not a standard C++ said:
typeof fits exactly my purposes.

The problem is that it is non-standard, so, like stat, it is off-topic in
this group.
Somehow it works *only* for static
declarations (for g++ at least). So, I could turn around the problem by
declaring a "dummy" no space taker member:
static struct stat sttype[0];

Then I can write:

typeof(sttype[0].st_gid) gid() const {return st.st_gid;}

Any better solution?

a) Read the manual
b) Ask in a group for your operating system
c) Ask in a group for your compiler
d) Wait for the next C++ standard
 
P

Paulo da Silva

Robert Bauck Hamar escreveu:
Paulo da Silva wrote: ....


a) Read the manual
b) Ask in a group for your operating system
c) Ask in a group for your compiler
d) Wait for the next C++ standard

I am sorry. I didn't know I needed a C++ lawyer degree to post here :)

Best regards.
 
E

Emery

Paulo said:
Any better solution?

C++ usually solves this kind of problem with templates. But if you are
trying to retain compatibility with a C library then you are out of
luck. For example:

template<class T>
struct stat
{
T gid;
};

template<class T>
class C
{
private:
stat<T> st;

public:
T gid() const
{
return st.gid;
}
};
 
K

Kai-Uwe Bux

Robert said:
Paulo da Silva wrote: [snip]
The example is clear.
I need to use the stat structure without knowing its members types, i.e.
I am not sure if they are standard or system dependent.

They are and are not standard.

They are not standard in that the C++ and C standards does not describe or
reference any struct stat.

They are standard in that POSIX describes them, and POSIX is a standard.
which is not a standard said:
typeof fits exactly my purposes.

The problem is that it is non-standard, so, like stat, it is off-topic in
this group.

Actually, the question whether C++ allows for typing of return values and
variables based upon the type of given expressions, and if so, how one does
this in C++, is topical. It just so happens that the answer is: it's not
(yet) possible. That the answer is short and not helpful does not render
the question off-topic.

Also, extensions of the standard, currently under discussion, are topical
according to the FAQ anyway. Since there are considerations about "auto"
and the likes of it, the problem of the OP seems to be perfectly topical.
That does not change the fact, that as of now, he will have to resort to
compiler specific solutions.


Best

Kai-Uwe Bux
 
K

kwikius

typeof(sttype[0].st_gid) gid() const {return st.st_gid;}

Any better solution?

Not a better solution but a conforming solution is a traits class
specialised on the particular class you wnat to find the member of and
#defined per compiler. You can make these so-called "type deduction"
schemes very sophisticated, but heres a simple example. Once the
traits class ( typeof_::member<Class, MemberTag> here) is defined, you
then use its member ::type in place of raw types. You can specialise
it on a case by case basis for implicity, though it can be made more
generic

Overall though the whole rigmarole of type deduction schemes is a pain
in the ass, and its a shame that C++ doesnt have the facitity. Its
daft because the compiler must know the type of an expression, it just
won't give it up

/*
example type deduction scheme

*/
// Only guessing !
extern "C" struct stat;

// use classes as tags to represent names
// no need to provide a definition
namespace member_tags{
struct st_gid;
}

namespace typeof_{

// declration only...
template <typename T, typename MemberTag>
struct member;

//specialise member by class and tag
// need to write and test per compiler
template<>
struct member<struct stat,member_tags::st_gid >{

#if defined(_MSC_VER)
typedef int type ; // only guessing don't know what it really
is
#elif defined(__GNUC__)
typedef short type ;
/*
...
*/
#else
#error need to define stat::st_gid for your compiler
#endif

};
}//typeof_


//Now work only in terms of the traits class
// rather than raw types...
typeof_::member<stat,member_tags::st_gid>::type my_fun()
{
typedef typeof_::member<stat,member_tags::st_gid>::type
result_type;
result_type i = 1;
return i;
}
#include <iostream>

int main()
{
std::cout << my_fun() <<'\n';
}


regards
Andy little
 
R

Robert Bauck Hamar

Emery said:
C++ usually solves this kind of problem with templates. But if you are
trying to retain compatibility with a C library then you are out of
luck. For example:

The problem is that stat is a struct defined by POSIX, and it is used in an
operating system call. That is, it's sole purpose is to be filled by a
system call, and using other types than the system expects, will fail,
probably with very subtle results. Google for "stat(2)", and you will find
information about it for different systems. So, the use of stat must reatin
compatibility with a C library.
template<class T>
struct stat
{
T gid;
};

template<class T>
class C
{
private:
stat<T> st;

public:
T gid() const
{
return st.gid;
}
};

The real gain had been if something like

decltype(st.st_gid) gid()

or

auto gid() { return st.st_gid; }

was possible. However it is not. Even if the compiler _knows_ which type
st_gid has, it is not possible to get this type from the compiler. However
this facility is proposed for the next C++ standard:
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2115.pdf.
 
E

Emery

The problem is that stat is a struct defined by POSIX, and it is used in an
operating system call. That is, it's sole purpose is to be filled by a
system call, and using other types than the system expects, will fail,
probably with very subtle results. Google for "stat(2)", and you will find
information about it for different systems. So, the use of stat must reatin
compatibility with a C library.

That's exactly what I was saying...
 
Joined
Sep 23, 2009
Messages
1
Reaction score
0
typeof

OK, I know this thread is rather old by now but, there might be a way around this typeof issue.

One could do something using templates and specialization, something like this:

Code:
#ifndef TYPEOF_H
#define TYPEOF_H

#include <string>

namespace Tools
{
  using namespace std;

  template<class T> static string typeof() { return "unknown"; }
  template<> static string typeof<bool>() { return "bool"; }
  template<> static string typeof<int>() { return "int"; }
  template<> static string typeof<double>() { return "double"; }

  template<class T> static string typeof(const T& t) { return typeof<T>(); }
}

#endif

This 'typeof' could be used like this:
Code:
#include "Typeof.h"

void main()
{
  std::string type = "";
  
  // v1
  type = Tools::typeof<bool>();

  // v2
  double d = 0.0;
  type = Tools::typeof(d);
}

Of course usually you might want do something depending on the T type, like the 'default' feature in C#. For that just write a 'default' template instead of finding out the type.

Others figured it out already probably but I just did it yesterday :D.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,755
Messages
2,569,537
Members
45,022
Latest member
MaybelleMa

Latest Threads

Top