使用 gcc 和 clang 在 C++ std::vector 构造中的不同行为
Different behaviour in C++ std::vector construction with gcc and clang
在下面的示例中,我期望 v
有 1 个元素,whos var
将是 Vector
类型并且将包含两个“int” Variant
s 10 和 20。
这是我在 gcc 中看到的行为。
使用 clang,'v' 包含两个元素,即两个“int”Variant
s 10 和 20。
我认为 gcc 的向量是通过 initializer_list 构造函数创建的,而 clang 的向量是通过移动构造函数创建的
这是某个编译器中的错误吗?我是否需要使 Variant
的构造函数成为 explicit
(这将迫使我像 Variant::Vector v{Variant{Variant::Vector{10, 20}}};
一样使用它。如果我想保留构造函数,是否还有其他方法可以避免此问题不明确?
用 https://wandbox.org/ and it behaves the same. Here are some links to try it directly: gcc, clang
中的所有 gcc 和 clang 版本尝试了此代码
#include <iostream>
#include <variant>
#include <vector>
struct Variant
{
using Vector = std::vector<Variant>;
Variant(const Vector & value)
{
var = value;
}
Variant(Vector && value)
{
var = std::move(value);
}
Variant(int value)
{
var = value;
}
std::variant<Vector, int> var;
};
int main()
{
Variant::Vector v{Variant::Vector{10, 20}};
std::cout << "v size: " << v.size() << ", index: " << v.at(0).var.index() << std::endl;
return 0;
}
这是CWG 2137,目前只有gcc实现
Clang 错误:https://github.com/llvm/llvm-project/issues/24186
另见 - 这稍微复杂一些,因为初始化列表元素 可从 其参数(被初始化的类型)构造,但诊断一样的,我也做不到比T.C更好的了。的描述:
Clang implemented DR 1467 (brace-initializing a T from a T behaves as if you didn't use braces) but has yet to implement DR 2137 (on second thought, do that only for aggregates).
如果您可以稍微更改程序语法,则可以添加另一层大括号:
Variant::Vector v{{Variant::Vector{10, 20}}};
或加括号:
Variant::Vector v({Variant::Vector{10, 20}});
在下面的示例中,我期望 v
有 1 个元素,whos var
将是 Vector
类型并且将包含两个“int” Variant
s 10 和 20。
这是我在 gcc 中看到的行为。
使用 clang,'v' 包含两个元素,即两个“int”Variant
s 10 和 20。
我认为 gcc 的向量是通过 initializer_list 构造函数创建的,而 clang 的向量是通过移动构造函数创建的
这是某个编译器中的错误吗?我是否需要使 Variant
的构造函数成为 explicit
(这将迫使我像 Variant::Vector v{Variant{Variant::Vector{10, 20}}};
一样使用它。如果我想保留构造函数,是否还有其他方法可以避免此问题不明确?
用 https://wandbox.org/ and it behaves the same. Here are some links to try it directly: gcc, clang
中的所有 gcc 和 clang 版本尝试了此代码#include <iostream>
#include <variant>
#include <vector>
struct Variant
{
using Vector = std::vector<Variant>;
Variant(const Vector & value)
{
var = value;
}
Variant(Vector && value)
{
var = std::move(value);
}
Variant(int value)
{
var = value;
}
std::variant<Vector, int> var;
};
int main()
{
Variant::Vector v{Variant::Vector{10, 20}};
std::cout << "v size: " << v.size() << ", index: " << v.at(0).var.index() << std::endl;
return 0;
}
这是CWG 2137,目前只有gcc实现
Clang 错误:https://github.com/llvm/llvm-project/issues/24186
另见
Clang implemented DR 1467 (brace-initializing a T from a T behaves as if you didn't use braces) but has yet to implement DR 2137 (on second thought, do that only for aggregates).
如果您可以稍微更改程序语法,则可以添加另一层大括号:
Variant::Vector v{{Variant::Vector{10, 20}}};
或加括号:
Variant::Vector v({Variant::Vector{10, 20}});