I saw some interesting compiler behavior yesterday and I think I understand why it's happening, but I want to be sure. So, I'm not going to write my reasoning, just the facts.
Note, it's not a typo that I've included vector
instead of string
. I did it intentionally so that the compiler would not be able to understand what an std::string was and so that it would have to search around to figure out which operator I'm referring to by +
:
#include <vector>
// #include <string> // intentionally commented out
template <typename T> struct A
{
A() { };
~A() { };
int m_member;
};
template <typename T> A<T> operator+(double lhs, const A<T> &rhs);
int main(int argc, char **argv)
{
std::string fullString = std::string("Hi ") + std::string("mom!");
}
So, I get a slew of compiler errors in MS Visual Studio 2005. I'm only showing a subset of them.
1>.\test.cpp(21) : error C2784: 'A<T> operator +(double,const A<T> &)' : could not deduce template argument for 'const A<T> &' from 'std::basic_string<_Elem,_Traits,_Ax>'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> .\test.cpp(16) : see declaration of 'operator +'
... errors continued ...
1>.\test.cpp(21) : error C2784: 'std::_Vb_iterator<_MycontTy> std::operator +(_Vb_iterator<_MycontTy>::difference_type,std::_Vb_iterator<_MycontTy>)' : could not deduce template argument for 'std::_Vb_iterator<_MycontTy>' from 'std::basic_string<_Elem,_Traits,_Ax>'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 8\VC\include\vector(1800) : see declaration of 'std::operator +'
... errors continued ...
1>.\test.cpp(21) : error C2784: 'std::_Vb_const_iterator<_MycontTy> std::operator +(_Vb_const_iterator<_MycontTy>::difference_type,std::_Vb_const_iterator<_MycontTy>)' : could not deduce template argument for 'std::_Vb_const_iterator<_MycontTy>' from 'std::basic_string<_Elem,_Traits,_Ax>'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 8\VC\include\vector(1695) : see declaration of 'std::operator +'
... errors continued ...
1>.\test.cpp(21) : error C2784: 'std::_Vector_iterator<_Ty,_Alloc> std::operator +(_Vector_iterator<_Ty,_Alloc>::difference_type,std::_Vector_iterator<_Ty,_Alloc>)' : could not deduce template argument for 'std::_Vector_iterator<_Ty,_Alloc>' from 'std::basic_string<_Elem,_Traits,_Ax>'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 8\VC\include\vector(396) : see declaration of 'std::operator +'
... errors continued ...
1>.\test.cpp(21) : error C2784: 'std::_Vector_const_iterator<_Ty,_Alloc> std::operator +(_Vector_const_iterator<_Ty,_Alloc>::difference_type,std::_Vector_const_iterator<_Ty,_Alloc>)' : could not deduce template argument for 'std::_Vector_const_iterator<_Ty,_Alloc>' from 'std::basic_string<_Elem,_Traits,_Ax>'
1> with
1> [
1> _Elem=char,
1> _Traits=std::char_traits<char>,
1> _Ax=std::allocator<char>
1> ]
1> C:\Program Files (x86)\Microsoft Visual Studio 8\VC\include\vector(264) : see declaration of 'std::operator +'
So, the compiler searches around for the what the +
means and complains that it can't deduce the appropriate template arguments. I'm surprised by two related things, one is that it gives this error for each overloaded +
operator that involves templates. This tells me that the compiler has absolutely no way of ruling out that any of these +
are not meaningful; two, which is related, that it doesn't just complain that no suitable operator exists.
I see this as an opportunity to learn something about how templates are instantiated and compiled. Does anyone have any good explanation or references?