C++ C++;17变体<;任何>;课内

C++ C++;17变体<;任何>;课内,c++,gcc,c++17,variant,C++,Gcc,C++17,Variant,以下代码编译得很好: int main() { variant<any> var; var = 5; cout << any_cast<int>(get<any>(var)) << endl; return 0; } intmain() { 变异变量; var=5; cout问题在于MyClass的隐式定义的复制构造函数,当它试图复制std::variant类型的成员时 要执行重载解析,编译器首先需要尝

以下代码编译得很好:

int main()
{
    variant<any> var;
    var = 5;
    cout << any_cast<int>(get<any>(var)) << endl;
    return 0;
}
intmain()
{
变异变量;
var=5;

cout问题在于
MyClass
的隐式定义的复制构造函数,当它试图复制
std::variant
类型的成员时

要执行重载解析,编译器首先需要尝试实例化所有
std::variant
的构造函数模板,函数参数为
const std::variant&
1。我们感兴趣的构造函数是:

template <class T> constexpr variant(T&& t) noexcept(/*...*/);
template constexpr variant(T&&T)noexcept(/*…*/);
仅当表达式
有趣时,它才参与重载解析(​性病​::​forward(t))
格式良好,其中
FUN
是根据.2生成的一组重载函数

在本例中,只有一种可选类型(
std::any
),因此只有一个虚构函数
FUN
,其签名为
FUN(std::any)
。现在,编译器需要决定是否可以使用
const std::variant&
1调用
FUN
。在此过程中,编译器需要知道是否可以使用
const std::variant&
1构造
std::any

这将触发
std::any
的构造函数模板
template any(T&&value);
的实例化,只有当
std::is­copy­constructible­v
true
VT
std::decation\t
,而
t
const std::variant&

现在为了查看
VT
(即
std::variant
)是否可以复制构造,编译器需要尝试实例化所有
std::variant
的构造函数模板……这就是我们开始的地方,我们陷入了一个循环

这可以解释为什么我们在错误消息中看到
模板constepr std::variant::variant(\u Tp&&)
\u重载集::\u S\u fun
(对应于上述函数
fun
),以及为什么我们看到相同的错误多次出现

GCC是如何从上述循环中断的,以及为什么调整程序可以阻止GCC报告错误,这仍然是一个问题。也许这些是某种错误的迹象


1.严格来说,它应该是“类型为
const std::variant
”的左值,而不是“a
const std::variant&


2.本标准还要求,如果
是相同的
错误的
.GCC(libstdc++),则该构造器只能参与过载解决选择稍后进行检查。我不知道这是否符合要求。

有趣的是,用值初始化替换默认初始化,使代码在GCC上可以正常编译。删除复制构造函数也会使代码编译:使用Visual Studio 2017和
/std:c++latest
标记编译第二个示例完美地运行。GCC要么被哄骗,要么MSVC侥幸脱险。我将进一步测试…CLAN也编译它,但仍然使用微软的C++实现。
template <class T> constexpr variant(T&& t) noexcept(/*...*/);