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, fromint
tobItem
and frombItem
tobNode
, 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
int
tobNode
, then it could be copy-initialized fromint
too.BTW:
bNode<bItem> node2(6);
performs direct initialization, which requiers only one implicit conversion (fromint
tobItem
), and the convertedbItme
is passed to the constructor ofbNode
to constructnode2
. It doesn't have such issue as copy initialization. (Copy-initialization likebNode<bItem> node2 = 6;
doesn't work either.)