在下面的示例中,我期望v有 1 个元素,其var类型为Vector并将包含两个“int” Variant10 和 20。这是我可以通过 gcc 看到的行为。
对于 clang,“v”包含两个元素,即两个“int” Variant10 和 20。
我认为gcc的向量是通过initializer_list构造函数创建的,而clang的向量是通过move构造函数创建的
这是其中一个编译器的错误吗?我是否需要创建Variant的构造函数explicit(这将迫使我像 一样使用它Variant::Vector v{Variant{Variant::Vector{10, 20}}};。如果我想让构造函数保持非显式,是否有其他方法可以避免此问题?
在https://wandbox.org/中的所有 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;
}
Run Code Online (Sandbox Code Playgroud)
这是CWG 2137,目前只有 gcc 实现。
铿锵错误:https://github.com/llvm/llvm-project/issues/24186
另请参见C++ 构造函数采用大小为 1 的 std::initializer_list - 这稍微复杂一些,因为初始化程序列表元素可以从其参数(正在初始化的类型)构造,但诊断是相同的,我不能比 TC 的描述更好:
Clang 实现了 DR 1467(从 T 中用大括号初始化 T 的行为就好像您没有使用大括号一样),但尚未实现 DR 2137(转念一想,仅对聚合执行此操作)。
如果您可以稍微更改程序语法,则可以添加另一级大括号:
Variant::Vector v{{Variant::Vector{10, 20}}};
Run Code Online (Sandbox Code Playgroud)
或者添加括号:
Variant::Vector v({Variant::Vector{10, 20}});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
600 次 |
| 最近记录: |