Urm*_*ahu 18 c++ c++11 visual-studio-2017
这段代码:
#include <vector>
#include <string>
#include <iostream>
class MyClass
{
public:
MyClass(const std::vector<std::vector<std::string>> & v)
{
std::cout << "Vector of string vectors size: " << v.size() << "\n";
for (size_t i = 0; i < v.size(); i++)
std::cout << "Vector #" << i << " has size " << v[i].size() << "\n";
}
};
int main()
{
MyClass({ { "a" } }); // <--- ok
MyClass({ { "a", "b" } }); // <--- PROBLEM
MyClass({ { std::string("a"), "b" } }); // <--- ok
MyClass({ { "a", "b", "c" } }); // <--- ok
MyClass({ { "a" },{ "c" } }); // <--- ok
MyClass({ { "a", "b" },{ "c", "d" } }); // <--- ok
}
Run Code Online (Sandbox Code Playgroud)
输出此(Visual Studio 2017):
Vector of string vectors size: 1
Vector #0 has size 1
Vector of string vectors size: 4
Vector #0 has size 97
Vector #1 has size 0
Vector #2 has size 0
Vector #3 has size 0
Vector of string vectors size: 1
Vector #0 has size 2
Vector of string vectors size: 1
Vector #0 has size 3
Vector of string vectors size: 2
Vector #0 has size 1
Vector #1 has size 1
Vector of string vectors size: 2
Vector #0 has size 2
Vector #1 has size 2
Run Code Online (Sandbox Code Playgroud)
因此,它在所有情况下都可以正常工作,除非我们有一个向量的向量,包含两个字符串.如果我们从其中一个字符串文字显式构造std :: string,它也适用于上述情况.如果两者都只是普通的字符串文字,编译器似乎会"混淆"并构造一个包含4个项目的向量,第一个包含97个字符串.注意97是字符代码"a".
我想我的问题是,编译器是否应该像我期望的那样解释这个有问题的结构,还是这个错误的代码来初始化这样的嵌套列表?
小智 17
内部向量MyClass({ { "a", "b" } })
是使用范围构造函数创建的:
template <class InputIterator>
vector (InputIterator first, InputIterator last, const allocator_type& alloc = allocator_type());
Run Code Online (Sandbox Code Playgroud)
发生这种情况是因为{ "a", "b" }
它不是被解释std::initializer_list<std::string>
为一对原始指针.
进入调试器中的违规构造函数会发现VC++已经选择了带有vector<vector<int>>
两个迭代器的构造函数(const char*
在这种情况下它们是s).
也就是说,它对待建筑就像
std::vector<std::vector<std::string>> {"a", "b"}
Run Code Online (Sandbox Code Playgroud)
当然,这会导致未定义的行为,因为两个指针不属于同一个数组.
作为旁注,g ++编译两者
std::vector<std::vector<std::string>> as{{"a", "b"}};
std::vector<std::vector<std::string>> bs{"a", "b"};
Run Code Online (Sandbox Code Playgroud)
但后者崩溃,而前者表现得像预期的那样.
VC++以你期望的方式编译双括号变量构造,所以我怀疑(希望)VC++中存在一个错误.