Topic: Determine return type at compile time?
Author: alf_p_steinbach@yahoo.no.invalid (Alf P. Steinbach)
Date: 12 Oct 02 07:45:30 GMT Raw View
Uhm, I'm moving this over to [comp.std.c++], perhaps someone there
knows...
Followup-To set to [comp.std.c++].
Cheers,
- Alf
On 9 Oct 2002 16:50:20 -0400, Daniel Spangenberg <dsp@bdal.de> wrote:
>Dear Alf,
>
>"Alf P. Steinbach" schrieb:
>
>> On 8 Oct 2002 11:05:58 -0400, Daniel Spangenberg <dsp@bdal.de> wrote:
>>
>
>[..]
>
>>
>> >partial specialization (The following code is not tested:
>> >
>> >// The generic template has to be explicitely "named":
>> > template< typename Arg, typename Result >
>> > struct FuncInfo1_
>> > {
>> > typedef Result ResultType;
>> > typedef Arg ArgType;
>> > };
>> >
>> >// The partial template does it automatically for "normal" function
>> >pointer:
>> > template <typename Arg, typename Result >
>> > struct FuncInfo1_ < Result (*)(Arg) >
>> > {
>> > typedef Result ResultType;
>> > typedef Arg ArgType;
>> > };
>>
>> Here's what Cygwin g++ 3.2 has to say about this technique:
>>
>> $ g++ returnType.cpp
>> returnType.cpp:15: wrong number of template arguments (1, should
be 2)
>> returnType.cpp:7: provided for `template<class Arg, class Result>
struct
>> FuncInfo1_'
>> returnType.cpp:16: confused by earlier errors, bailing out
>>
>> In the attempt at a partial specialization,
>>
>> "<Result(*)(Arg)>"
>>
>> is evidently interpreted as an actual argument list for
>>
>> "<typename Arg, typename Result>".
>>
>> So, as far as I understand it, the above is incorrect usage.
>>
>
>Sorry, but I think the compiler goes wrong. For an example of this
technique
>see Scott Meyer's articles in Dr. Dobbs:
>
>http://www.ddj.com/documents/s=898/ddj9910b/9910b.htm
>and
>http://www.ddj.com/documents/s=898/ddj9910b/9910bs1.htm
>
>and look at listening 12 (of course the remaining article is
interessting too,
>because it concentrates on the simulation of closure classes;-):
>
>[..]
>
>template <typename T> // traits class
>struct MemFuncTraits {};
>
>template <typename R, typename O> // partial specialization
>struct MemFuncTraits<R (O::*)()> { // for zero-parameter
> typedef R ReturnType; // non-const member
> typedef O ObjectType; // functions
>};
>
>template <typename R, typename O> // partial specialization
>struct MemFuncTraits<R (O::*)() const> { // for zero-parameter
> typedef R ReturnType; // const member
> typedef O ObjectType; // functions
>};
>
>template <typename R, typename O, typename P1> // partial
specialization
>struct MemFuncTraits<R (O::*)(P1)> { // for one-parameter
> typedef R ReturnType; // non-const member
> typedef O ObjectType; // functions
>};
>
>[..]
>
>This is what the ISO standard says:
>
>One of the key sentences are 14.5.4.1 Mathing of class template partial
>specializations, p. 2:
>"A partial specialization matches a given actual template argument list
if the
>template arguments of the partial specialization can
>be deduced from the actual template argument list (14.8.2) [..]"
>
>On the other hand, 14.8.2. p. 9 presents a list of template arguments
which
>should be deducable:
>[..]
>type (*)(T)
>type (type::*)(T)
>[..]
>
>> >// Similar specializations may be provided for other cases like
member
>> >function
>> >// pointer:
>> > template <typename Obj, typename Arg, typename Result >
>> > struct FuncInfo1_ < Result (Obj::*)(Arg) >
>> > {
>> > typedef Result ResultType;
>> > typedef Arg ArgType;
>> > typedef Obj ObjType; // optional
>> > };
>> >
>> >But be aware that not every compiles does support this fully
>> >standard-compliant partial specialization stuff!
>>
>> Ditto.
>
>Should also work.
[ 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 ]
Author: alf_p_steinbach@yahoo.no.invalid (Alf P. Steinbach)
Date: 12 Oct 02 21:27:23 GMT Raw View
On 11 Oct 2002 05:02:36 -0400, Andrey Tarasevich <andreytarasevich@hotmail.com>
wrote:
>Daniel Spangenberg wrote:
>> ...
>> and look at listening 12 (of course the remaining article is
>interessting too,
>> because it concentrates on the simulation of closure classes;-):
>>
>> [..]
>>
>> template <typename T> // traits class
>> struct MemFuncTraits {};
>>
>> template <typename R, typename O> // partial specialization
>> struct MemFuncTraits<R (O::*)()> { // for zero-parameter
>> typedef R ReturnType; // non-const member
>> typedef O ObjectType; // functions
>> };
>>
>> template <typename R, typename O> // partial specialization
>> struct MemFuncTraits<R (O::*)() const> { // for zero-parameter
>> typedef R ReturnType; // const member
>> typedef O ObjectType; // functions
>> };
>>
>> template <typename R, typename O, typename P1> // partial
>specialization
>> struct MemFuncTraits<R (O::*)(P1)> { // for one-parameter
>> typedef R ReturnType; // non-const member
>> typedef O ObjectType; // functions
>> };
>>
>> [..]
>
>Well, this version of the code is nothing like the code that you
>presented
>in your previous message. The code in the previous message contained an
>obvious error, reported by GCC (any other compliant compiler should
>report
>it too).
>
>This version is free of this error.
Could you explan what the obvious error is that isn't present?
(Not my code, I hasten to add, I just don't understand this.)
Cheers,
- Alf
(Cross-posted to comp.std.c++)
[ 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 ]
Author: pavel@despammed.com ("Pavel Kuznetsov")
Date: Sun, 13 Oct 2002 04:05:28 +0000 (UTC) Raw View
Alf P. Steinbach (alf_p_steinbach@yahoo.no.invalid) writes
>>>> partial specialization (The following code is not tested:
>>>>
>>>> // The generic template has to be explicitely "named":
>>>> template< typename Arg, typename Result >
>>>> struct FuncInfo1_
>>>> {
>>>> typedef Result ResultType;
>>>> typedef Arg ArgType;
>>>> };
>>>>
>>>> // The partial template does it automatically for "normal" function
>>>> pointer:
>>>> template <typename Arg, typename Result >
>>>> struct FuncInfo1_ < Result (*)(Arg) >
>>>> {
>>>> typedef Result ResultType;
>>>> typedef Arg ArgType;
>>>> };
>>> Here's what Cygwin g++ 3.2 has to say about this technique: <...>
Here's correct sample, which "works":
// NOTE: only one template parameter here
template< typename T >
struct FuncInfo1_;
// The partial template does it automatically for
// "normal" function pointer:
template <typename Arg, typename Result >
struct FuncInfo1_ < Result (*)(Arg) >
{
typedef Result ResultType;
typedef Arg ArgType;
};
--
Pavel
---
[ 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: alf_p_steinbach@yahoo.no.invalid (Alf P. Steinbach)
Date: Sun, 13 Oct 2002 09:38:29 +0000 (UTC) Raw View
On Sun, 13 Oct 2002 04:05:28 +0000 (UTC), pavel@despammed.com ("Pavel Kuznetsov")
wrote:
>Alf P. Steinbach (alf_p_steinbach@yahoo.no.invalid) writes
>
>>>>> partial specialization (The following code is not tested:
>>>>>
>>>>> // The generic template has to be explicitely "named":
>>>>> template< typename Arg, typename Result >
>>>>> struct FuncInfo1_
>>>>> {
>>>>> typedef Result ResultType;
>>>>> typedef Arg ArgType;
>>>>> };
>>>>>
>>>>> // The partial template does it automatically for "normal" function
>>>>> pointer:
>>>>> template <typename Arg, typename Result >
>>>>> struct FuncInfo1_ < Result (*)(Arg) >
>>>>> {
>>>>> typedef Result ResultType;
>>>>> typedef Arg ArgType;
>>>>> };
>
>>>> Here's what Cygwin g++ 3.2 has to say about this technique: <...>
>
>Here's correct sample, which "works":
>
> // NOTE: only one template parameter here
> template< typename T >
> struct FuncInfo1_;
>
> // The partial template does it automatically for
> // "normal" function pointer:
> template <typename Arg, typename Result >
> struct FuncInfo1_ < Result (*)(Arg) >
> {
> typedef Result ResultType;
> typedef Arg ArgType;
> };
Thanks -- that's what I also ended up with, essence being that
in this context "Result(*)Arg" is a type, not a function pointer.
Of course, to supply that type to the template, at least with a
conforming compiler, one has to specify it directly at some point,
or construct it from direct specifications. No way, AFAICS, of
obtaining it from a function definition, unless one uses "typeof"
which is not yet standard (g++ accepts the above with "typeof").
So, in conclusion, the code that Scott Meyers presented in the DDJ
article referred to in the original clc++m thread, Listing 12 in
[http://www.ddj.com/documents/s=898/ddj9910b/9910b.htm], is
correct as far as it goes, but what it does is *not* to obtain the
return type from a function; it just obtains the return type
from a function type, which is something else entirely.
I wish Scott could have been even more clear on that, so we'd
avoided this debate -- at least one person (not me) interpreted
it as an example of how to obtain the return type from a function.
Cheers,
- Alf
(Still open issue: any *proof* that typeof or some other language
extension is needed to obtain the return type of a function?)
---
[ 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: Andrey Tarasevich <andreytarasevich@hotmail.com>
Date: 13 Oct 2002 17:43:15 -0400 Raw View
Alf P. Steinbach wrote:
>> ...
>>Well, this version of the code is nothing like the code that you
>>presented
>>in your previous message. The code in the previous message contained an
>>obvious error, reported by GCC (any other compliant compiler should
>>report
>>it too).
>>
>>This version is free of this error.
>
> Could you explan what the obvious error is that isn't present?
> ...
Others have already pointed the error out. Daniel's original code was
declaring a class template with two template parameters. Later on he was
referring to that template as having only one template parameter (in the
partial specialization of the template). That's an error.
This is his original template declaration:
template< typename Arg, typename Result>
struct FuncInfo1_
{
typedef Result ResultType;
typedef Arg ArgType;
};
This is his partial specialization:
template <typename Arg, typename Result >
struct FuncInfo1_< Result (*)(Arg) > // ERROR: second parameter missing
{
typedef Result ResultType;
typedef Arg ArgType;
};
The above specialization is not valid in C++.
--
Best regards,
Andrey Tarasevich
Brainbench C and C++ Programming MVP
---
[ 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 ]