Reputation: 2576
This snippet has an typo on the last line (missing qualifier ::type).
template<bool ci> struct comp { typedef ci_compare_string type; };
template< > struct comp<false> { typedef std::less<std::string> type; };
template <typename T, bool ci = true> //map w str keys, case sensitive option
struct mapx : std::map<std::string, T, typename comp<ci> > {}; // oops, should be comp_<ci>::type
The VS 2008 compiler reported the error at the std::map source line shown below. The message was "term does not evaluate to a function taking 2 arguments".
...
mapped_type& operator[](const key_type& _Keyval)
{ // find element matching _Keyval or insert with default mapped
iterator _Where = this->lower_bound(_Keyval);
if (_Where == this->end()
|| this->comp(_Keyval, this->_Key(_Where._Mynode()))) <=== ERROR !!!!
_Where = this->insert(_Where,
value_type(_Keyval, mapped_type()));
return ((*_Where).second);
}
};
...
So eventually I figured out that the error must have to do with the comparator, and then I stared and stared until I realized that I forgot to type "::type".
I haven't worked much w templates before and would like to know the right way to trace back a compiler error like this one. Any tips / tricks one is supposed to use in this type of situation ?
Upvotes: 2
Views: 1099
Reputation: 354969
The message was "term does not evaluate to a function taking 2 arguments"
In Visual Studio, the Error List shows only the first line of any error message. It is meant to be an easy-to-glance-through summary of errors. Some error messages are very long, especially when templates are involved. The complete error message can be found in the Output window for the Build.
When an error occurs during template instantiation, the compiler will print the stack of templates that it was instantiating when the error was detected. For example, when I compile your snippet with Visual C++ 2012, it prints the following error (Visual C++ 2008 will print a similar message, though it will necessarily be different because of differences in the Standard Library implementation):
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xtree(1792) : error C2064: term does not evaluate to a function taking 2 arguments
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xtree(1153) : see reference to function template instantiation 'std::pair<_Ty1,_Ty2> std::_Tree<_Traits>::_Insert_nohint<std::pair<const _Kty,_Ty>&,std::_Tree_node<_Value_type,_Voidptr>*>(bool,_Valty,_Nodety)' being compiled
with
[
_Ty1=std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const std::string,int>>>>,
_Ty2=bool,
_Traits=std::_Tmap_traits<std::string,int,comp<true>,std::allocator<std::pair<const std::string,int>>,false>,
_Kty=std::string,
_Ty=int,
_Value_type=std::pair<const std::string,int>,
_Voidptr=void *,
_Valty=std::pair<const std::string,int> &,
_Nodety=std::_Tree_node<std::pair<const std::string,int>,void *> *
]
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xtree(1153) : see reference to function template instantiation 'std::pair<_Ty1,_Ty2> std::_Tree<_Traits>::_Insert_nohint<std::pair<const _Kty,_Ty>&,std::_Tree_node<_Value_type,_Voidptr>*>(bool,_Valty,_Nodety)' being compiled
with
[
_Ty1=std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const std::string,int>>>>,
_Ty2=bool,
_Traits=std::_Tmap_traits<std::string,int,comp<true>,std::allocator<std::pair<const std::string,int>>,false>,
_Kty=std::string,
_Ty=int,
_Value_type=std::pair<const std::string,int>,
_Voidptr=void *,
_Valty=std::pair<const std::string,int> &,
_Nodety=std::_Tree_node<std::pair<const std::string,int>,void *> *
]
stubby.cpp(12) : see reference to function template instantiation 'std::pair<_Ty1,_Ty2> std::_Tree<_Traits>::insert<std::pair<const char *,int>>(_Valty &&)' being compiled
with
[
_Ty1=std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const std::string,int>>>>,
_Ty2=bool,
_Traits=std::_Tmap_traits<std::string,int,comp<true>,std::allocator<std::pair<const std::string,int>>,false>,
_Valty=std::pair<const char *,int>
]
stubby.cpp(12) : see reference to function template instantiation 'std::pair<_Ty1,_Ty2> std::_Tree<_Traits>::insert<std::pair<const char *,int>>(_Valty &&)' being compiled
with
[
_Ty1=std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<std::pair<const std::string,int>>>>,
_Ty2=bool,
_Traits=std::_Tmap_traits<std::string,int,comp<true>,std::allocator<std::pair<const std::string,int>>,false>,
_Valty=std::pair<const char *,int>
]
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xtree(1796) : error C2064: term does not evaluate to a function taking 2 arguments
C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\INCLUDE\xtree(1817) : error C2064: term does not evaluate to a function taking 2 arguments
Now, this is still not particularly easy to read or user-friendly by any definition of those terms. But it does show you where the error occurred. The three top-level errors occur on lines 1792, 1796, and 1817 of <xtree>
, and all of those lines attempt to use the comparer to compare two arguments.
Upvotes: 4