微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

通过模板模板类数组的参数推导进行隐式初始化

如何解决通过模板模板类数组的参数推导进行隐式初始化

我有一个item类,实际上就是一个int的包装器。 我有一个模板化的节点类。我将项目类作为模板参数传递给它。

我想创建模板化节点类的数组,但是编译器不喜欢它。 当我使用相同的语法创建单个对象时,它将起作用。 为什么不能推导数组元素来初始化模板化类的数组? 创建模板化类的对象数组的正确方法是什么?

这里的项目类是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;
    }
};

这里有模板化的Node类

#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),next(nullptr) {}
    ~bNode() {
        delete prev;
        delete next;
    }
    
    friend ostream& operator<<(ostream& os,const bNode& node) {
        os << "node " << node.item<< endl;
        return os;
    }
};

这是main()

int main()
{    
    bNode<bItem> nodes[5]{ 1,2,3,4,5 }; //this does not compile
    bNode<bItem> node2(6); //this compiles ok

}

这是错误消息

error C2440: 'initializing': cannot convert from 'int' to 'bNode<bItem>'
message : No constructor Could take the source type,or constructor overload resolution was ambiguous

解决方法

在数组的aggregate initialization中,元素是来自初始化程序列表的相应子句中的copy-initialized。这意味着类型bNode<bItem>的元素需要从int复制初始化,这需要两次用户定义的隐式转换,从intbItem和{{ 1}}到bItem,这是不允许的。

每个bNode数组元素或非静态类成员,按类定义中数组下标/外观的顺序,位于初始化器列表的相应子句中copy-initialized

作为解决方法,您可以限制隐式转换的时间,例如

direct public base,(since C++17)

或者您可以在bNode<bItem> nodes[5] = { bItem(1),bItem(2),bItem(3),bItem(4),bItem(5) }; 中添加另一个使用int的构造函数,然后也可以从bNode复制初始化。

int

BTW:// forward it to bNode::bNode(itemType) bNode(int val) : bNode(itemType(val)) {} 执行direct initialization,仅需要一次隐式转换(从bNode<bItem> node2(6);int),然后将转换后的bItem传递给bItme的构造函数以构造bNode。它没有copy initialization这样的问题。 (像node2这样的复制初始化也不起作用。)

此外,复制初始化中的隐式转换必须直接从初始值设定项产生T,而例如直接初始化需要从初始值设定项到T的构造函数的参数的隐式转换。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。