Topic: Typedefs and Exception Specifications


Author: terje.s@chello.no (=?ISO-8859-1?Q?Terje_Sletteb=F8?=)
Date: Mon, 17 Jun 2002 18:02:21 GMT
Raw View
"Paul Mensonides" <pmenso57@attbi.com> wrote in message news:<6PLO8.209199$cQ3.6804@sccrnsc01>...

> After reading the newest issue of CUJ, I have a question revolving around
> typedefs and exception specifications.  While I know that they are not allowed
> directly

What isn't allowed directly, you mean? Could you give a code example?

>, I wondering if the following is legal:
>
> template<class T> struct type_to_type {
>      typedef T type;
> };
>
> void f() {
>      return;
> }
>
> int main() {
>      typedef type_to_type<void (*)() throw(int)>::type type;
>      type pf = &f;
>      return 0;
> }

The typedef should be legal, I think.

However, as you say here, you get an error at the assignment, because
of the type mismatch.

> Comeau C++ allows the indirect typedef and even preserves the semantics of the
> exception specification.

What's indirect about this? You have a typedef, taking a template
instantiation, where the type given is pointer to function, and that
template yields an inner type, "type". Ah, I guess you mean indirect,
as in using a typedef on a template instantiation, that itself uses a
typedef, to give the result.

Well, as mentioned, it should be legal, it will just instantiate the
template first, to get the inner typedef. Code like this is used a lot
in libraries like Loki.

Also, as you said, it compiles on Comeau C++, when f() gets a matching
exception specification.

> In the code above, it yields an error about the
> exception specification conflict of 'f' and 'void (*)() throw(int)'.

Yes, and that is as it should be. The exception specification is part
of the function signature.

> If I signature of 'f' to include the appropriate exception specification, then
> everything compiles fine.
>
> It is also interesting to note that explicit and partial specializations still
> match:
>
> #include <iostream>
>
> template<class T> struct type_to_type {
>      typedef T type;
> };
>
> template<class T> struct test {
>      enum { value = 0 };
> };
>
> template<> struct test<void (*)()> {
>      enum { value = 1 };
> };
>
> int main() {
>      typedef type_to_type<void (*)() throw(int)>::type type;
>      std::cout << test<type>::value << &std::endl;
>      return 0;
> }
>
> Any thoughts?

That's quite interesting. When compiling the above code on Intel C++
(which uses the EDG front end, like Comeau C++), the above prints "1",
showing that it prefers the total specialisation, even if it isn't a
complete match to the calling argument (the exception specification is
different). I would think it would have selected the base template,
instead, since it's not a complete match.


Regards,

Terje

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Giovanni Bajo" <giovannibajo@REMOVEliberoTHIS.it>
Date: Mon, 17 Jun 2002 20:59:35 GMT
Raw View
"Terje Sletteb   " <terje.s@chello.no> ha scritto nel messaggio
news:acfcd061.0206170456.edae8ec@posting.google.com...

> > After reading the newest issue of CUJ, I have a question revolving
around
> > typedefs and exception specifications.  While I know that they are not
allowed
> > directly
>
> What isn't allowed directly, you mean? Could you give a code example?

Your mail missed the main point, which is that the following code is
ill-formed:

typedef void (*something)(void) throw(); // exception specification can be
typedef'd.

Paul presented some meta-programming that seems to achieve the same effect
through a smart indirection through a template, and he was wondering if his
code is legal or not, and I tend to doubt that a final answer exists.

Giovanni Bajo

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Paul Mensonides" <pmenso57@attbi.com>
Date: Mon, 17 Jun 2002 22:16:03 GMT
Raw View
"Giovanni Bajo" <giovannibajo@REMOVEliberoTHIS.it> wrote in message
news:PjrP8.29534$j65.704755@twister1.libero.it...

> Your mail missed the main point, which is that the following code is
> ill-formed:
>
> typedef void (*something)(void) throw(); // exception specification can be
> typedef'd.
>
> Paul presented some meta-programming that seems to achieve the same effect
> through a smart indirection through a template, and he was wondering if his
> code is legal or not, and I tend to doubt that a final answer exists.
>
> Giovanni Bajo

How about this?

#include <iostream>

template<class A, class B = A> struct test;

template<class R, class B> struct test<R (*)(void), B> {
    typedef R (* a)(void);
    typedef B b;
};

int f() {
    std::cout << "f() called." << &std::endl;
    return 0;
}

int main() {
    typedef test<int (*)(void) throw(int)> scope;
    scope::a pf = &f;
    (*pf)();
    scope::b pg = &f;
    (*pg)();
    return 0;
}

The exception specification is only carried through 'pg'.

Paul Mensonides

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: "Paul Mensonides" <pmenso57@attbi.com>
Date: Sat, 15 Jun 2002 21:16:04 GMT
Raw View
[I posted this to comp.lang.c++.moderated a few days ago, but no one replied.
So sorry to all of you that may have seen it but ignored it.]

After reading the newest issue of CUJ, I have a question revolving around
typedefs and exception specifications.  While I know that they are not allowed
directly, I wondering if the following is legal:

template<class T> struct type_to_type {
     typedef T type;
};

void f() {
     return;
}

int main() {
     typedef type_to_type<void (*)() throw(int)>::type type;
     type pf = &f;
     return 0;
}

Comeau C++ allows the indirect typedef and even preserves the semantics of the
exception specification.  In the code above, it yields an error about the
exception specification conflict of 'f' and 'void (*)() throw(int)'.

If I signature of 'f' to include the appropriate exception specification, then
everything compiles fine.

It is also interesting to note that explicit and partial specializations still
match:

#include <iostream>

template<class T> struct type_to_type {
     typedef T type;
};

template<class T> struct test {
     enum { value = 0 };
};

template<> struct test<void (*)()> {
     enum { value = 1 };
};

int main() {
     typedef type_to_type<void (*)() throw(int)>::type type;
     std::cout << test<type>::value << &std::endl;
     return 0;
}

Any thoughts?

Paul Mensonides


      [ Send an empty e-mail to c++-help@netlab.cs.rpi.edu for info ]
      [ about comp.lang.c++.moderated. First time posters: do this! ]

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]