Why does the line indicated ( in main() ) in the following code not compile?
#include <iostream>
#include <string>
#include <map>
template< typename _T > struct Inventory : public std::map< _T, int >
{
bool getat(int i, _T &t, int &n)
{
if ((i < 0) || (i >= (int)this->size())) return false;
int c=0;
typename std::map< _T, int >::iterator it = this->begin();
while ((c < i) && (it != this->end())) { c++; it++; }
t = (*it).first;
n = (*it).second;
return true;
}
Inventory &operator=(_T t) { (*this)[t]++; return *this; }
Inventory &operator,(_T t) { return operator=(t); }
};
int main()
{
int i=0, quantity;
std::string item;
//***Fails to compile:***
//Inventory< std::string > inv = "a","b","c","a","c","d","e";
Inventory< std::string > inv;
inv = "a","b","c","a","c","d","e"; //but this is fine
inv = "e","f";
while (i < (int)inv.size())
{
if (inv.getat(i, item, quantity))
std::cout << i << ": " << item << " -> " << quantity << "\n";
i++;
}
return 0;
}
That's called copy-initialization. In short, it uses the conversion constructor and then the copy constructor to construct inv
, not operator =
as you expect.
Inventory< std::string > inv = "a","b","c","a","c","d","e";
is invalid syntax. Something like Inventory< std::string > inv = "a"
would first attempt to create a temporary Inventory
from "a","b","c","a","c","d","e"
and then use that temporary as argument to a copy constructor to construct inv
. operator =
is never called in this case.
Your second version works because
Inventory< std::string > inv;
calls the default constructor, and
inv = "a","b","c","a","c","d","e";
calls operator =
on an already initialized object.