C++ template problem

925486d41a872ebda2879c8108143ab8
0
Harry 101 Aug 30, 2007 at 10:46

Hello, this is my first time on this forum so please bear with me! I saw another post titled ‘c++ call templated function on template parameter’ which solved a problem someone was having with templates so I know people here know what they are talking about.

I have a project which was written for PPC2003 using embedded VisualC++. I have now converted it to Visual Studio 2005 but it will not build.

The problem is to do with a template definition in a file called ‘stl_alloc.h’ which is 3rd party freeware code which I did not write. Here is the code:

template <bool __threads, int __inst>
typename __default_alloc_template<__threads, __inst>::_Obj* __STL_VOLATILE
__default_alloc_template<__threads, __inst> ::_S_free_list[
# if defined(__SUNPRO_CC) || defined(__GNUC__) || defined(__HP_aCC)
_NFREELISTS
# else
__default_alloc_template<__threads, __inst>::_NFREELISTS
# endif
] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };

This looks quite messy to the untrained eye. I get the following errors:

>.\stl\stl_alloc.h(572) : warning C4346: ‘std::__default_alloc_template<threads,inst>::_Obj’ : dependent name is not a type

1> prefix with ‘typename’ to indicate a type
1>.\stl\stl_alloc.h(572) : error C2143: syntax error : missing ‘;’ before ‘*’ 1>.\stl\stl_alloc.h(572) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>.\stl\stl_alloc.h(572) : error C2888: ‘__default_alloc_template<threads,inst>::_Obj _Obj’ : symbol cannot be defined within namespace ‘std’
1>.\stl\stl_alloc.h(572) : fatal error C1903: unable to recover from previous error(s); stopping compilation

These errors all point to line 572 (which I have indicated via a comment above-Its the second line in the code above). If I look at the first warning C4346 I am told in MSDN Help that:

“The typename keyword is required if a dependent name is to be treated as a type. This is a breaking change in the Visual C++ .NET 2003 compiler, made in order to conform to the ISO C++ standard.”

So I believe that there has been a change in the way typenames have been defined for Visual Studio 2003.

Does anyone know how the above code should be re-written or changed so my project will compile?

Thanks

Harry

12 Replies

Please log in or register to post a reply.

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Aug 30, 2007 at 11:21

[please post code in

...[ /code] tags for better readability :(]

As you can see, __default_alloc_template<__threads, __inst>::_Obj is already prefixed with 'typename', so I don't get the error.

It's weird. I managed to reproduce that exact same error:
[code]namespace std
{

    template<class T> struct A
    {
        typedef int Foo;
    };
    
    template<class T> struct B
    {
        static typename A<T>::Foo foo;
    };

    template<class T> A<T>::Foo B<T>::foo;

}

1>c:\\main.cpp(16) : warning C4346: 'std::A<T>::Foo' : dependent name is not a type
1>        prefix with 'typename' to indicate a type
1>c:\\main.cpp(16) : error C2143: syntax error : missing ';' before 'std::B<T>::foo'
1>c:\\main.cpp(16) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>c:\\main.cpp(16) : error C2888: 'A<T>::Foo Foo' : symbol cannot be defined within namespace 'std'
1>c:\\main.cpp(16) : fatal error C1903: unable to recover from previous error(s); stopping compilation

By changing that last line to

template<class T> typename A<T>::Foo B<T>::foo;

The errors went away. Are you sure the code is exactly as stated in your post?

925486d41a872ebda2879c8108143ab8
0
Harry 101 Aug 30, 2007 at 11:45

Thanks for the reply. Yes I have posted the code exactly. I have tried putting ‘typename’ in again but I still cant get rid of the problem.

Here is is again just to be sure (with a few lines b4 and after):

template <bool __threads, int __inst>
size_t __default_alloc_template<__threads, __inst>::_S_heap_size = 0;

template <bool __threads, int __inst>
typename __default_alloc_template<__threads, __inst>::_Obj* __STL_VOLATILE
__default_alloc_template<__threads, __inst> ::_S_free_list[
# if defined(__SUNPRO_CC) || defined(__GNUC__) || defined(__HP_aCC)
    _NFREELISTS
# else
    __default_alloc_template<__threads, __inst>::_NFREELISTS
# endif
] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, };
// The 16 zeros are necessary to make version 4.1 of the SunPro
// compiler happy.  Otherwise it appears to allocate too little
// space for the array.

#endif /* ! __USE_MALLOC */

Have you seen this type of problem before?

Thanks again.

Harry

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Aug 30, 2007 at 12:08

What errors do you get if you remove that typename altogether?
And can you post the complete class definition of __default_alloc_template<threads,inst>?

925486d41a872ebda2879c8108143ab8
0
Harry 101 Aug 30, 2007 at 12:25

I removed it and I appear to get the same errors

>.\stl\stl_alloc.h(572) : warning C4346: 'std::__default_alloc_template<threads,inst>::_Obj' : dependent name is not a type
1>        prefix with 'typename' to indicate a type
1>.\stl\stl_alloc.h(572) : error C2143: syntax error : missing ';' before '*'
1>.\stl\stl_alloc.h(572) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>.\stl\stl_alloc.h(572) : error C2888: '__default_alloc_template<threads,inst>::_Obj _Obj' : symbol cannot be defined within namespace 'std'
1>.\stl\stl_alloc.h(572) : fatal error C1903: unable to recover from previous error(s); stopping compilation

Here is the class definition

template <bool threads, int inst>
class __default_alloc_template {

private:
  // Really we should use static const int x = N
  // instead of enum { x = N }, but few compilers accept the former.
#if ! (defined(__SUNPRO_CC) || defined(__GNUC__))
    enum {_ALIGN = 8};
    enum {_MAX_BYTES = 128};
    enum {_NFREELISTS = 16}; // _MAX_BYTES/_ALIGN
# endif
  static size_t
  _S_round_up(size_t __bytes) 
    { return (((__bytes) + (size_t) _ALIGN-1) & ~((size_t) _ALIGN - 1)); }

__PRIVATE:
  union _Obj {
        union _Obj* _M_free_list_link;
        char _M_client_data[1];    /* The client sees this.        */
  };
private:
# if defined(__SUNPRO_CC) || defined(__GNUC__) || defined(__HP_aCC)
    static _Obj* __STL_VOLATILE _S_free_list[]; 
        // Specifying a size results in duplicate def for 4.1
# else
    static _Obj* __STL_VOLATILE _S_free_list[_NFREELISTS]; 
# endif
  static  size_t _S_freelist_index(size_t __bytes) {
        return (((__bytes) + (size_t)_ALIGN-1)/(size_t)_ALIGN - 1);
  }

If you type ‘stl_alloc.h’ into google then you will get the complete file as the first gogle hit.

Thanks again for taking time to help me.

Harry

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Aug 30, 2007 at 12:48

Ok, now put it back, and before the ‘template <bool __threads, int __inst>’ line above, put

#undef typename

Does that change anything in the error messages?

925486d41a872ebda2879c8108143ab8
0
Harry 101 Aug 30, 2007 at 12:56

The original error messages are not there but now i get the following error messages for a file called ‘stl_iterator.h’

1>.\stl\stl_iterator.h(51) : error C4980: '__value' : use of this keyword requires /clr:oldSyntax command line option
1>.\stl\stl_iterator.h(51) : error C3630: error when processing the token '__value'
1>        .\stl\stl_iterator.h(58) : see reference to class template instantiation 'std::back_insert_iterator<_Container>' being compiled
1>.\stl\stl_iterator.h(51) : fatal error C1190: managed targeted code requires a '/clr' option

here is the line 51 it refers to:

template <class _Container>
class back_insert_iterator {
protected:
  _Container* container;
public:
  typedef _Container          container_type;
  typedef output_iterator_tag iterator_category;
  typedef void                value_type;
  typedef void                difference_type;
  typedef void                pointer;
  typedef void                reference;

  explicit back_insert_iterator(_Container& __x) : container(&__x) {}
  back_insert_iterator<_Container>&
  operator=(const typename _Container::value_type& __value) {  //line 51
    container->push_back(__value);
    return *this;
  }
  back_insert_iterator<_Container>& operator*() { return *this; }
  back_insert_iterator<_Container>& operator++() { return *this; }
  back_insert_iterator<_Container>& operator++(int) { return *this; }
};

Thanks again

Harry

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Aug 30, 2007 at 14:03

__value was a keyword in the now deperecated managed extensions for C++. I think there’s no other solution than simply replacing all occurrences of __value with a name that is not a keyword (you could try adding an extra underscore)

However, regarding your previous problem, I find it very scary that someone #defines ‘typename’ to be something else. I think you’ll need to find the causer of the problem, rather than just fixing it in the way I described. You could do a find in all files for “#define typename”

925486d41a872ebda2879c8108143ab8
0
Harry 101 Aug 30, 2007 at 14:50

I have replaced all __value with ‘__valueTest ‘ and now the following errors show:

1>.\stl\string(1102) : warning C4346: 'std::basic_string<_CharT,_Traits,_Alloc>::size_type' : dependent name is not a type
1>        prefix with 'typename' to indicate a type
1>.\stl\string(1102) : error C2143: syntax error : missing ';' before 'std::basic_string<_CharT,_Traits,_Alloc>::npos'
1>.\stl\string(1102) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>.\stl\string(1102) : error C2888: 'basic_string<_CharT,_Traits,_Alloc>::size_type size_type' : symbol cannot be defined within namespace 'std'

I’m really sorry to pester you with all these errors, if you have a link to anywhere which would explain all this then I would be most grateful. I have a feeling that I’m gonna experience error after error after error:(

Thanks

Harry

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Aug 30, 2007 at 14:58

Same story as with the stl_alloc.h. Someone is doing a ‘#define typename <something>’, you should find out who’s doing it.

925486d41a872ebda2879c8108143ab8
0
Harry 101 Aug 30, 2007 at 15:18

OK thank you for all your help :)

Harry

925486d41a872ebda2879c8108143ab8
0
Harry 101 Aug 31, 2007 at 14:28

Here is an answer I got from another forum:

BEGIN
The easiest thing for you to do, believe it or not is to get rid of that stl folder from your project. Just nuke it, delete it, whatever – the Visual Studio 2005 compiler shouldn’t be even taking a sniff of that third-party STL.

When you recompile your program, you will probably get other errors that certain STL classes are functions can’t be found. In that case, the issue is that you’re not pointing to the compiler’s header directory, or your source code still has something like:

Code:

#include “thirdpartystl\stl_header”
Then you need to include the actual standard header, instead of the third-party STL header.

Here is a sample of a valid C++ program that uses STL:

#include <string>
#include <vector>
#include <iostream>

using namespace std;
int main()
{
   vector<int> IntVect(10);
   IntVect[0] = 1;
   string s = "Hello World";
   cout << s;
}

This should compile with no problems with Visual Studio 2005. The issue that you are having is that standard C++ headers such as <vector>, <string> were not created for the eVC4 compiler. So that is why whoever had the project previously needed to use a third-party STL product.

Now that STL is part of standard C++, it comes with every standard C++ compiler, including Visual Studio 2005. For Visual Studio 2005, you don’t need to set anything to use STL. Just write the code, compile, and run. The problem you’re having is that your project still points to and uses the third-party evc4 version of STL. So that is why I stated you should just get rid of that STL, compile, and fix any errors.

Regards,

Paul McKenzie
END

Now all i did was delest the folder called ‘stl’ from my project and I was able to proceed(There were other errors though but I was able to work through them as they were MFC based)

Thanks

Harry

340bf64ac6abda6e40f7e860279823cb
0
_oisyn 101 Aug 31, 2007 at 14:52

Yes, that is also a possibility. I was in the understanding that you needed the other STL implementation for some reason :)