使用初始化器列表设置insert
std::set insert with initialiser lists
我有这个简单的代码:
struct Base
{
Base(int xx, int yy) : x(xx), y(yy){}
bool operator<(const Base& b) const {return (x < b.x) || (x==b.x && y < b.y);}
int x;
int y;
};
struct D1 : Base
{
D1(int x, int y) : Base(x, y){}
};
struct D2 : Base
{
D2(int x = 0, int y = 0) : Base(x, y){}
};
void test()
{
std::set<D1> s1;
std::set<D2> s2;
s1.insert({1, 2});
s2.insert({1, 2});
std::cout<<"s1 size:"<<s1.size()<<std::endl<<"Content:"<<std::endl;
for(auto& v : s1)
{
std::cout<<v.x<<" "<<v.y<<std::endl;
}
std::cout<<std::endl<<"s2 size:"<<s2.size()<<std::endl<<"Content:"<<std::endl;
for(auto& v : s2)
{
std::cout<<v.x<<" "<<v.y<<std::endl;
}
}
输出:
s1 size:1
Content:
1 2
s2 size:2
Content:
1 0
2 0
为什么在插入带有默认参数的对象时行为不同?这是一个错误还是它的预期行为?
PS:您可以在这里看到操作代码:https://ideone.com/UPArOi
这里的经验法则是initializer_list<X>
重载比其他重载更受欢迎。
首先,from [over.ics.list]
如果形参类型为
std::initializer_list<X>
,且初始化列表的所有元素都可以当隐式转换为X
时,隐式转换序列是转换an所需的最差转换元素转换为X
,或者如果初始化列表没有元素,则进行标识转换。这种转换可以即使在调用初始化列表构造函数的上下文中,也是用户定义的转换。
And, from [over.ics.rank]:
如果列表初始化序列L1是比列表初始化序列L2更好的转换序列- L1转换为
std::initializer_list<X>
的X
和L2不[…]
我们有两个相关的std::set::insert
重载:
std::pair<iterator,bool> insert( value_type&& value );
void insert( std::initializer_list<value_type> ilist );
第一次调用:
s1.insert({1, 2});
考虑参数类型为std::initializer_list<D1>
的重载。1
和2
都不能隐式地转换为D1
,因此重载是不可行的。现在考虑D1&&
过载。由于可以用该初始化列表构造D1
,因此它是被选择的重载,最后得到一个元素:D1{1, 2}
。
然而,在这种情况下:
s2.insert({1, 2});
这是标准行为。这是因为您使用1
和2
都可以隐式地转换为D2
,这要归功于D2
的构造函数中的默认参数。所以initializer_list<D2>
过载是可行的。D2&&
重载也是可行的,但是initializer_list
转换序列是一个更好的转换序列,所以它是首选。这给了我们两个元素,D2{1}
和D2{2}
。initialization list
到insert
到您的set
。这对默认参数的作用是为每个int
创建两个对象(使用第二个参数的默认值)。
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 在C++/Linux中设置单调时钟的一些技巧
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 嵌套在类中时无法设置成员数据
- 需要帮助设置在C++中使用的Potrace
- 如何在自删除后将对象设置为nullptr
- 将指针设置为"nullptr"并不能防止双重删除?
- 如何在Ubuntu中使用cmake设置qt4
- ld:bind_at_load和-bitcode_bundle(Xcode设置ENABLE_bitcode=YES)不能
- 如何在boost beast http请求中设置http头
- 如何解决gcc编译器优化导致的centos双编译器设置中的分段错误
- 如何将这个C++哈希表转换为动态扩展和收缩,而不是使用硬设置的最大值
- Insert函数不适用于2 if语句C++
- 为什么文件名被设置为一个点,而不是在读取矢量中的文件名时
- 如何在24位SDL_Surface上设置像素的颜色
- std::设置自定义比较器
- 如何设置一个范围来提取我想要获得的信息
- 仍然可以设置::insert cause BSOD
- 使用初始化器列表设置insert
- C++ STL 映射和设置容器的 insert() 函数违反了默认参数的规则?