cw/template instantiation question

Hi all, I am having a typeof test problem in cw, which I tracked down to inability to compile the following: typedef std::binder1st< int > type2; // error The error message is: Error : illegal use of template argument dependent type 'T::first_argument_type' Looks like something causes the compiler to instantiate the template... Interestingly, the other similar constructs seem to do fine: typedef std::binary_negate< int > type1; // OK Thanks in advance for any advice. Also I would greatly appreciate, if somebody could send me the sources of CW's binder1st and binary_negate (functional.hpp) Regards, Arkadiy

On Dec 11, 2005, at 7:29 AM, Arkadiy Vertleyb wrote:
Hi all,
I am having a typeof test problem in cw, which I tracked down to inability to compile the following:
typedef std::binder1st< int > type2; // error
The error message is: Error : illegal use of template argument dependent type 'T::first_argument_type'
Looks like something causes the compiler to instantiate the template...
Interestingly, the other similar constructs seem to do fine:
typedef std::binary_negate< int > type1; // OK
Thanks in advance for any advice.
If you put: #include <mslconfig> #undef _MSL_EXTENDED_BINDERS high up in the translation unit (configuration maybe?), then the typedef will compile. Are you sure you want to do things like this? The type int does not meet the requirements for these template parameters. For example in std::binder1st<Operation>, the requirements include: 1. Operation has a nested type named first_argument_type. 2. Operation has a nested type named second_argument_type. 3. Operation has a nested type named result_type. If your intent is simply to get a typeof working on cw, it might be easier to map to its existing __typeof__ facility. #include <functional> #define typeof __typeof__ int main() { typeof(std::bind1st(std::greater<int>(), 5)) f = std::bind1st (std::greater<int>(), 5); bool b = f(3); }
Also I would greatly appreciate, if somebody could send me the sources of CW's binder1st and binary_negate (functional.hpp)
Unfortunately these are not open sourced. -Howard

Howard Hinnant wrote:
On Dec 11, 2005, at 7:29 AM, Arkadiy Vertleyb wrote:
...
typedef std::binder1st< int > type2; // error
...
Are you sure you want to do things like this? The type int does not meet the requirements for these template parameters. For example in std::binder1st<Operation>, the requirements include:
1. Operation has a nested type named first_argument_type. 2. Operation has a nested type named second_argument_type. 3. Operation has a nested type named result_type.
It doesn't matter. The requirements don't apply unless binder1st<int> is instantiated, and it isn't in the above example. binder1st<int> is still incomplete unless it's used in a context that demands a complete type. Unless the compiler has a bug, the only explanation is nonstandard default arguments.

"Howard Hinnant" <hinnant@twcny.rr.com> wrote
On Dec 11, 2005, at 7:29 AM, Arkadiy Vertleyb wrote:
Hi all,
I am having a typeof test problem in cw, which I tracked down to inability to compile the following:
typedef std::binder1st< int > type2; // error [...]
If you put:
#include <mslconfig> #undef _MSL_EXTENDED_BINDERS
high up in the translation unit (configuration maybe?), then the typedef will compile.
Aha! Interesting... So they did "extend" their binders in some way, which probaby causes the problem...
Are you sure you want to do things like this? The type int does not meet the requirements for these template parameters. For example in std::binder1st<Operation>, the requirements include:
1. Operation has a nested type named first_argument_type. 2. Operation has a nested type named second_argument_type. 3. Operation has a nested type named result_type.
I understand this. We just use this technique to pass the template around as a type, and later extract it using partial template specialization: template<template<class> class Tpl, class T> class x<Tpl<T> > { // use Tpl and ignore T }; I believe "typedef binder1st<int> type;" should be OK (and is OK with the rest of compilers, at least in the regression's release view) since it's not supposed to cause binder1st instantiation... If I am not mistaken, the same technique is used by MPL in its lambda.
If your intent is simply to get a typeof working on cw, it might be easier to map to its existing __typeof__ facility.
We have this, but I generally want to have also standard-compliant emulation working. Just in case one wants to write code in cw, which is supposed to also work, say, in vc8.
Also I would greatly appreciate, if somebody could send me the sources of CW's binder1st and binary_negate (functional.hpp)
Unfortunately these are not open sourced.
I see... Then is it possible to take a look inside, and see what is so specific about binder "extension" that causes the problem with this particular templates? (unless this kind of thing is also not allowed with their licence) Regards, Arkadiy

Arkadiy Vertleyb wrote:
"Howard Hinnant" <hinnant@twcny.rr.com> wrote
Also I would greatly appreciate, if somebody could send me the sources of CW's binder1st and binary_negate (functional.hpp)
Unfortunately these are not open sourced.
I see...
Then is it possible to take a look inside, and see what is so specific about binder "extension" that causes the problem with this particular templates?
(unless this kind of thing is also not allowed with their licence)
It doesn't matter what their license says, posting the declaration of std::binder1st for the purposes of researching the reason for its non-conformance to an international standard must qualify as fair use. Or we are all criminals. http://www.metrowerks.com/mw/download/

On Dec 11, 2005, at 10:49 AM, Arkadiy Vertleyb wrote:
Then is it possible to take a look inside, and see what is so specific about binder "extension" that causes the problem with this particular templates?
Peter hit the nail on the head (as usual).
Unless the compiler has a bug, the only explanation is nonstandard default arguments.
template <class Operation, class T = typename Metrowerks::remove_reference<Operation>::type::first_argument_type> class binder1st ... It is wrapped in: #ifdef _MSL_EXTENDED_BINDERS with the standard version in the #else. _MSL_EXTENDED_BINDERS is defined by default in <mslconfig> which every CodeWarrior std C++ header includes. The intent was to create a binder1st that could hold the operation by reference if desired in order to avoid copies of expense-to-copy predicates (such as those holding a container to compare to). tr1::ref is probably a better solution to that problem, as is tr1::bind. Consider this a failed experiment on my part. -Howard

"Howard Hinnant" <hinnant@twcny.rr.com> wrote
template <class Operation, class T = typename Metrowerks::remove_reference<Operation>::type::first_argument_type> class binder1st ...
It is wrapped in:
#ifdef _MSL_EXTENDED_BINDERS
with the standard version in the #else. _MSL_EXTENDED_BINDERS is defined by default in <mslconfig> which every CodeWarrior std C++ header includes.
The intent was to create a binder1st that could hold the operation by reference if desired in order to avoid copies of expense-to-copy predicates (such as those holding a container to compare to). tr1::ref is probably a better solution to that problem, as is tr1::bind. Consider this a failed experiment on my part.
Thanks a lot for this information. Although failed the experiment might be, I'll have to find a workaround for this... I assume if I supply the second argument, it should be fine: typedef binder1st<int, int> type; (I will know once the next regression runs) Regards, Arkadiy
participants (3)
-
Arkadiy Vertleyb
-
Howard Hinnant
-
Peter Dimov