I have an item class, thats really a wrapper around an int. I have a templated node class. I pass item class to it as template parameter.
I want to create an array of the templated node class, but compiler does not like it. When I create a single object using the same syntax, it works. Why cant it deduce the array elements to initialize array of templated class? What is the correct way of creating an array of objects of a templated class?
Heres item class, which is a wrapper around an int.
using namespace std;
class bItem {
private :
int item{INT_MIN};
public:
bItem() : item(INT_MIN) {}
bItem(int val) : item(val) {}
int getItem() { return item; }
bItem operator==(const bItem& val) {
return item == val.item;
}
bItem operator>(const bItem& val) {
return item > val.item;
}
bItem operator<(const bItem& val) {
return item < val.item;
}
friend ostream& operator<<(ostream& os, const bItem& item) {
os << "value:" << item.item << endl;
return os;
}
};
Heres the templated Node class
#include <iostream>
using namespace std;
template<class itemType>
class bNode {
itemType item{};
bNode* prev{};
bNode* next{};
public:
bNode() : item(), prev(nullptr), next(nullptr) {}
bNode(itemType _item) : item(_item), prev(nullptr), next(nullptr) {}
~bNode() {
delete prev;
delete next;
}
friend ostream& operator<<(ostream& os, const bNode& node) {
os << "node " << node.item<< endl;
return os;
}
};
and heres the main()
int main()
{
bNode<bItem> nodes[5]{ 1,2,3,4,5 }; //this does not compile
bNode<bItem> node2(6); //this compiles ok
}
and here is the error message
error C2440: 'initializing': cannot convert from 'int' to 'bNode<bItem>'
message : No constructor could take the source type, or constructor overload resolution was ambiguous
In aggregate initialization of array, the elements are copy-initialized from the corresponding clause of the initializer list. That means the element with type
bNode<bItem>needs to be copy-initialized from theint, which requires two user-defined implicit conversions, frominttobItemand frombItemtobNode, which is not allowed.As the workaround you could impose restrictions on the times of implicit conversions, e.g.
Or you can add another constructor taking
inttobNode, then it could be copy-initialized frominttoo.BTW:
bNode<bItem> node2(6);performs direct initialization, which requiers only one implicit conversion (frominttobItem), and the convertedbItmeis passed to the constructor ofbNodeto constructnode2. It doesn't have such issue as copy initialization. (Copy-initialization likebNode<bItem> node2 = 6;doesn't work either.)