I have a class template (ExclusiveMap) which takes two type parameters C1 and C2 and declares two private members map<C1, C2> and map<C2, C1> (both STL maps). In test code I instantiate this class template providing types int and string for C1 and C2 respectively.

The test code compiles cleanly using GCC 3.2 however when I pass it through HPUX aCC I get error messages about the inability to convert strings to ints.

I can appreciate that aCC might be stricter than GCC in certain aspects however I cannot understand how GCC would compile and link it with no errors or warnings resulting in an executable that actually does what I want whereas aCC quits with errors, not just warnings.

Can anyone see what might be causing aCC to require conversion from string to int in the code below?

test.cc:
=======

#include <ExclusiveMap.h>
#include <string>
#include<iostream>
using namespace std;

class FloeLog
{

public:

    void init();

private:

     ExclusiveMap<int, string>  _logTypeMap;  // aCC does not seem to like
//    ExclusiveMap<int, int>  _logTypeMap;  // No compile errors

}; // class FloeLog

void FloeLog::init()
{
    cout << "Inside FloeLog::init(), about to do _logTypeMap.insert()\n";

      _logTypeMap.insert(12, "FLOE_EVENT");
//    _logTypeMap.insert(12, 13); // No compile errors
}

int main()
{

FloeLog FL;

FL.init();

return 0;
}

ExclusiveMap.h:
============

#include <map>
using namespace std;

template <class C1, class C2>
class ExclusiveMap
{
public:

    ExclusiveMap();

    bool insert(const C1& c1, const C2& c2);

private:

    map<C1, C2> _map1;
    map<C2, C1> _map2;
};

 
template <class C1, class C2>
ExclusiveMap<C1, C2>::ExclusiveMap()
{
}

 

template <class C1, class C2>
bool
ExclusiveMap<C1, C2>::insert(const C1& c1, const C2& c2)
{

     typename map<C1, C2>::iterator map1Iter = _map1.find(c1);
     typename map<C2, C1>::iterator map2Iter = _map2.find(c2); // This causes compile error when using HP aCC

     if (map1Iter ==  _map1.end() && map2Iter == _map2.end())
     {
       _map2[c2] = c1;
       _map1[c1] = c2;
        return true;
     }
    return false;
}

% g++ -g -I. test.cc
<compiles and links without errors>


% /opt/aCC/bin/aCC -AA -c -g -I. test.cc
Error 226: "/opt/aCC-3.30.01/include_std/rw/tree.cc", line 492 # No appropriate function found for call of 'operator ()'. Last viable
candidate was "bool std::less<int>::operator ()(const int &,const int &) const" ["/opt/aCC-3.30.01/include_std/functional", line
167]. Argument of type 'const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &' could not be converted to
'const int &'.
if (!_C_key_compare(__x->_C_key(), __k))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error 226: "/opt/aCC-3.30.01/include_std/rw/tree.cc", line 500 # No appropriate function found for call of 'operator ()'. Last viable
candidate was "bool std::less<int>::operator ()(const int &,const int &) const" ["/opt/aCC-3.30.01/include_std/functional", line
167]. Argument of type 'const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &' could not be converted to
'const int &'.
|| _C_key_compare(__k, ((_C_tree_iter&)__j)._C_node->_C_key())) ? e
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Error 556: "./ExclusiveMap.h", line 33 # Unable to generate specialization "__rw::__rw_tree_iter<std::pair<const
std::basic_string<char,std::char_traits<char>,std::allocator<char> >,int>,long,std::pair<const int,int> *,std::pair<const int,int>
&,__rw::__rw_rb_tree_node<std::allocator<std::pair<const int,int> >,std::pair<const
std::basic_string<char,std::char_traits<char>,std::allocator<char>
>,int>,std::basic_string<char,std::char_traits<char>,std::allocator<char> >,__rw::__select1st<std::pair<const
std::basic_string<char,std::char_traits<char>,std::allocator<char>
>,int>,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > > >
__rw::__rb_tree<std::basic_string<char,std::char_traits<char>,std::allocator<char> >,std::pair<const
std::basic_string<char,std::char_traits<char>,std::allocator<char> >,int>,__rw::__select1st<std::pair<const
std::basic_string<char,std::char_traits<char>,std::allocator<char>
>,int>,std::basic_string<char,std::char_traits<char>,std::allocator<char> > >,std::less<int>,std::allocator<std::pair<const
int,int> > >::find(const std::basic_string<char,std::char_traits<char>,std::allocator<char> > &)" due to errors during generation.
typename map<C2, C1>::iterator map2Iter = _map2.find(c2); // This causes compile error when using HP aCC
^^^^^^^^^^^^^^
Error 440: "/opt/aCC-3.30.01/include_std/utility", line 117 # Cannot initialize 'const int' with 'const class
basic_string<char,std::char_traits<char>,std::allocator<char> >'.
: first (__rhs.first), second (__rhs.second) { }
^^^^^^^^^^^

Recommended Answers

All 2 Replies

As far as I know, this code is fine on a standard implementation. It seems that the underlying problem is that aCC doesn't have a "less" comparator for string types. Try implementing your own comparator for the string class and pass it as template argument in the declaration of _map2.

Thanks for your reply. I agree that the error messages do suggest so. However I trimmed my original code down to its barest minimum such that aCC still errors out on it complaining about type mismatches (while g++ still compiles it fine). I am amazed by what I find.

Test.cc:

#include <map>
#include <string>
using namespace std;

template <class C1, class C2>
class ExclusiveMap
{
    map<C1, C2> _map1;
    map<C2, C1> _map2;
};

class FloeLog
{

     ExclusiveMap<int, string>  _logTypeMap;  
//   ExclusiveMap<string, int>  _logTypeMap2;  
};


int main()
{

FloeLog FL;
return 0;

}

% g++ -g -I. Test.cc
<compiles and links without errors>

% /opt/aCC/bin/aCC -AA -g -I. Test.cc
Error (future) 212: "/opt/aCC-3.30.01/include_std/rw/tree", line 454 # Argument type 'const std::pair<const int,int> *' does not match
expected parameter type 'std::pair<const int,int> *'.
_RWSTD_VALUE_ALLOC
^^^^^^^^^^^^^^^^^^
Error 440: "/opt/aCC-3.30.01/include_std/utility", line 117 # Cannot initialize 'const int' with 'const class
basic_string<char,std::char_traits<char>,std::allocator<char> >'.
: first (__rhs.first), second (__rhs.second) { }
^^^^^^^^^^^
Error 445: "Test.cc", line 20 # Cannot recover from earlier errors.
int main()
^^^^^^^^^^


If I swap the order of passing types <int, string> to be <string, int> like this:

Test.cc:

#include <map>
#include <string>
using namespace std;

template <class C1, class C2>
class ExclusiveMap
{
    map<C1, C2> _map1;
    map<C2, C1> _map2;
};

class FloeLog
{

//    ExclusiveMap<int, string>  _logTypeMap;  
      ExclusiveMap<string, int>  _logTypeMap2;  
};


int main()
{

FloeLog FL;
return 0;

}

% /opt/aCC/bin/aCC -AA -g -I. Test.cc
Error (future) 212: "/opt/aCC-3.30.01/include_std/rw/tree", line 454 # Argument type 'const std::pair<const
std::basic_string<char,std::char_traits<char>,std::allocator<char>
>,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > *' does not match expected parameter type
'std::pair<const std::basic_string<char,std::char_traits<char>,std::allocator<char>
>,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > *'.
_RWSTD_VALUE_ALLOC
^^^^^^^^^^^^^^^^^^
Error 226: "/opt/aCC-3.30.01/include_std/utility", line 117 # No appropriate function found for call of 'basic_string::basic_string'.
Last viable candidate was "std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string(const
std::allocator<char> &)" ["/opt/aCC-3.30.01/include_std/string", line 204]. Argument of type 'const int' could not be converted to
'const std::allocator<char> &'.
: first (__rhs.first), second (__rhs.second) { }
^^^^^^^^^^^
Error 445: "Test.cc", line 20 # Cannot recover from earlier errors.
int main()
^^^^^^^^^^

i.e. a slightly different error message but essentially the same thing.

Now here's the really strange thing: If I comment out the second map instantiation map<C2, C1> _map2 then aCC compiles and links Test.cc with no errors emitted.

Test.cc:

#include <map>
#include <string>
using namespace std;

template <class C1, class C2>
class ExclusiveMap
{
    map<C1, C2> _map1;
//    map<C2, C1> _map2;
};

class FloeLog
{

      ExclusiveMap<int, string>  _logTypeMap;  
      ExclusiveMap<string, int>  _logTypeMap2;  
};


int main()
{

FloeLog FL;
return 0;

}

% /opt/aCC/bin/aCC -AA -g -I. Test.cc
<compiles and links without errors>

Given the symmetry in that I'm instantiating two ExclusiveMap classes, one with <int, string> and the other with <string, int> you'd think that if the above compiles cleanly then so too should the following where I've commented out _map1 instead of _map2:

Test.cc:

#include <map>
#include <string>
using namespace std;

template <class C1, class C2>
class ExclusiveMap
{
//    map<C1, C2> _map1;
    map<C2, C1> _map2;
};

class FloeLog
{

      ExclusiveMap<int, string>  _logTypeMap; 
      ExclusiveMap<string, int>  _logTypeMap2; 
};


int main()
{

FloeLog FL;
return 0;

}

But no.

% /opt/aCC/bin/aCC -AA -g -I. Test.cc
Error (future) 212: "/opt/aCC-3.30.01/include_std/rw/tree", line 454 # Argument type 'const std::pair<const
std::basic_string<char,std::char_traits<char>,std::allocator<char>
>,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > *' does not match expected parameter type
'std::pair<const std::basic_string<char,std::char_traits<char>,std::allocator<char>
>,std::basic_string<char,std::char_traits<char>,std::allocator<char> > > *'.
_RWSTD_VALUE_ALLOC
^^^^^^^^^^^^^^^^^^
Error 226: "/opt/aCC-3.30.01/include_std/utility", line 117 # No appropriate function found for call of 'basic_string::basic_string'.
Last viable candidate was "std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_string(const
std::allocator<char> &)" ["/opt/aCC-3.30.01/include_std/string", line 204]. Argument of type 'const int' could not be converted to
'const std::allocator<char> &'.
: first (__rhs.first), second (__rhs.second) { }
^^^^^^^^^^^
Error 445: "Test.cc", line 20 # Cannot recover from earlier errors.
int main()
^^^^^^^^^^

Needless to say I am completely baffled by what I am seeing and at this stage I can think of no other cause than a bug in aCC.

I would be very interested to hear if anyone feels otherwise - thanks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.