template extremly implicit instantiation

MS VC 7.1++

Here is the code, that using typeof implementation by Bill Gibbons ( http://www.accu-usa.org/2000-05-Main.html ):

[code]

#include <ostream>
using namespace std;
//for typeof
template<int N> struct typeof_c; // No definition, only specializations

/**/
#define REGISTER_TYPE(N,T) \
    template<> struct typeof_c<N> { typedef T RET; }; \
  typedef char CharArrayOf ## N ## [ ## N ## ]; \
  typedef CharArrayOf ## N *PtrCharArrayOf ## N ## ; \
  PtrCharArrayOf ## N typeof_f( T ); \
/**/

#define register_type( n, type ) REGISTER_TYPE( n, type )
/**/


#define typeof(x) typeof_c<sizeof(*typeof_f(x))>::RET


register_type( 1, ostream& )

struct test1_ {
  ostream& f() { return cout; }
};

template< class T1 >
struct result_of {
        static T1 t1;
  static test1_ t2;

  typedef typename typeof( t1.f() ) T2; //error
  typedef typename typeof( t2.f() ) T3; //ok
};

[/code]

But compiler generates error concerned with typedef ... T2:

error C2027: use of undefined type 'typeof_c'

But result_of doesnt appear any more in the programm. So, what kind of "instantiation" is this And why it's happens And how can I solve this problem

Is this problem solved in studion 8.0

Also, there is another, but very similar, problem appears if You will put register_type in the end of this code.

P.S.:
Erreneous string after preprocessing:

typedef typename typeof_c<sizeof(*typeof_f(t1.f()))>::RET T2;




Answer this question

template extremly implicit instantiation

  • ShornScrotum

    I'm not a preprocessor expert, but I'm fairly certain that the code engenders undefined behavior. The token pasting operator should only be used if the result is a single preprocessing token.

    Therefore it should be:

    typedef char CharArrayOf ## N [ N ]; \
    typedef CharArrayOf ## N *PtrCharArrayOf ## N ; \

    Anyway, it looks like VC++ doesn't realize that T2 is a dependent name. It should not be instantiated until it is used (which it is not in your example). Please do file a bug report at http://lab.msdn.microsoft.com/productfeedback/Default.aspx .

    As a workaround, you might wrap size of in a metafunction:

    template < int N > struct sizeof_ { static const int value = N; };

    and

    #define typeof(x) typeof_c<sizeof_<sizeof(*typeof_f(x))>::value>::RET

    That said, you might want to take a look a boost typeof, which should work just fine with all mainstream compilers.


  • Bonnie P

    OH, YES!

    This is it! Thank You so much! Wrapper solved the problem.

    I will check out the boost typeof, but I've had some troubles downloading newest version of mpl before.

    Thanks alot.



  • template extremly implicit instantiation