C++ 嵌套初始值设定项列表每个包含单个项的列表的模糊性

C++ 嵌套初始值设定项列表每个包含单个项的列表的模糊性,c++,nested,implicit-conversion,initializer-list,C++,Nested,Implicit Conversion,Initializer List,我正在编写一个置换类,我想使用初始值设定项列表(一种形式表示法)或嵌套初始值设定项列表(循环表示法)来初始化它。我遇到了一个重载消歧错误,为此我准备了以下示例: #include <iostream> #include <initializer_list> class SomeClass{ public: SomeClass(std::initializer_list<int> init) { std::cout << "Const

我正在编写一个置换类,我想使用初始值设定项列表(一种形式表示法)或嵌套初始值设定项列表(循环表示法)来初始化它。我遇到了一个重载消歧错误,为此我准备了以下示例:

#include <iostream>
#include <initializer_list>
class SomeClass{
public:
  SomeClass(std::initializer_list<int> init)
  {
    std::cout << "Constructor 1" << std::endl;
  }

  SomeClass(std::initializer_list<std::initializer_list<int>> init)
  {
    std::cout << "Constructor 2" << std::endl;
  }
};

int main()
{
  SomeClass({{1},{2}});
  return 0;
}
#包括
#包括
上课{
公众:
SomeClass(std::初始值设定项\列表初始化)
{

std::cout单个元素
{1}
会自动转换为
1
。编译器不知道构造函数使用的是哪个版本,因为两者都是正确的。我认为这可能是个问题。在c++11中,可以使用这样的初始化:
int a{1};
正如您所说,
{1}
{2}
在您的示例中,可以使用直接列表初始化将其转换为
int 1
int 2
,因此会出现歧义。 例如,在N33 37(C++标准草案)中,有85.4表示

避免这种歧义的一种简单方法是使用双大括号
{{…}
,并显式创建
std::initializer\u list
。 例如,下面的代码使用嵌套的初始值设定项列表
{{int{1}}、{int{2}}
调用
SomeClass
的第二个构造函数:

SomeClass({ {{1}}, {{2}} });
SomeClass({ { {1}, {2} } });
下面的代码使用嵌套的初始值设定项列表调用第二个构造函数
{{int{1},int{2}}

SomeClass({ { {1}, {2} } });
直接列表初始化和复制列表初始化也是这样工作的:


试着使构造函数显式地
?它不会改变任何东西。问题不是某些函数正在使用这些构造函数隐式地转换它的输入。问题是{1}被隐式地转换为1。我必须取消整型“构造函数”我需要说的是:不要隐式转换这个函数的参数。
SomeClass({ { {1}, {2} } });
// direct-list-initialization
SomeClass a{ {{1}}, {{2}} }; // Constructor 2 with a nested initializer_list { { int{1} }, { int{2} }}
SomeClass b{ { {1}, {2} } }; // Constructor 2 with a nested initializer_list { { int{1}, int{2} } }

// copy-list-initialization
SomeClass d = { {{1}}, {{2}} }; // Constructor 2 with a nested initializer_list { { int{1} }, { int{2} }}
SomeClass e = { { {1}, {2} } }; // Constructor 2 with a nested initializer_list { { int{1}, int{2} } }