首先,没有使用接受初始化列表的构造函数,因为这样的构造函数看起来像:
basic_string(initializer_list<charT>, const Allocator& = Allocator());
^^^^^
因此,编译器会搜索另一个适当的构造函数,并找到了这样一个构造函数。它就是构造函数。
template<class InputIterator>
basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator());
表达式"one"
和"two"
被视为类型为const char *
的迭代器。
因此,函数test
具有未定义的行为。
例如,您可以编写以下代码(前提是相同内容的字符串文字在内存中作为一个字符串文字存储,但这不能保证,并取决于所选的编译器选项)。
#include <iostream>
#include <string>
void test(const std::string &value) { std::cout << "string overload: " << value << std::endl; }
int main()
{
test({ "one", "one" + 3 });
}
而且您将获得一个有效的结果。
string overload: one
请注意,这个结构是关于IT技术的。
{ "one", "two" }
不是std :: initializer_list <T>
类型的对象。这个结构没有类型。它是一个braced-init-list
,用作初始化器。简单来说,编译器会首先尝试使用第一个参数为std :: initializer_list类型的构造函数与此初始化程序一起使用。
例如,如果您使用std :: vector<const char *>
类,那么编译器确实将使用其带有std :: initializer_list的构造函数,并相应地使用这个大括号初始化程序来初始化其参数。例如:
#include <iostream>
#include <vector>
int main()
{
std::vector<const char *> v( { "one", "two" } );
for ( const auto &s : v ) std::cout << s << ' ';
std::cout << '\n';
}
initializer_list
版本的std::string
仅适用于字符列表,而不是字符串列表。对于字符串列表,您将获得对象的标准列表初始化。当不含糊时,注释重载是可以的。例如,如果列表有两个以上的元素。 - sklott