std :: visit的以下用法在gcc 7.2下正确编译,但无法在clang 5.0下编译.有谁知道问题是什么?
#include <variant>
struct S1 {int foo() { return 0; }};
struct S2 {int foo() { return 1; }};
using V = std::variant<S1, S2>;
int bar() {
V v;
return std::visit([](auto& s) { return s.foo(); }, v);
}
Run Code Online (Sandbox Code Playgroud)
第一个错误是这样的:
include/c++/7.2.0/variant:238:46: error: cannot cast 'std::variant<S1, S2>' to its private base class
'std::__detail::__variant::_Variant_storage<true, S1, S2>'
return __get(std::in_place_index<_Np>, std::forward<_Variant>(__v)._M_u);
Run Code Online (Sandbox Code Playgroud)
这是一个链接到godbolt显示此错误:https://godbolt.org/g/5iaKUm
有人可以解释为什么以下代码为f2打印0?似乎= {}以某种方式解析为int赋值运算符.
#include <iostream>
struct Foo
{
Foo() : x {-1} {}
Foo(int x) : x{x} {}
Foo& operator=(int y) { x = y; return *this; }
Foo& operator=(const Foo& f) { x = f.x; return *this; }
int x;
};
int main()
{
Foo f1 = {};
Foo f2;
f2 = {};
std::cout << f1.x << '\n'; // this prints -1
std::cout << f2.x << '\n'; // this prints 0
}
Run Code Online (Sandbox Code Playgroud) 以下代码使用gcc 6.3(https://godbolt.org/g/sVZ8OH)编译时没有任何错误/警告,但由于下面标记的内存访问无效,它包含危险的未定义行为.根本原因是在emplace_back中执行的隐式转换.任何人都可以建议一个好的方法或最佳做法,以避免代码中的此类错误?
#include <iostream>
#include <vector>
struct Foo
{
explicit Foo(const int& i) : i{i} {}
void foo() const { std::cout << i; } // invalid memory access, as i is an invalid ref!!
const int& i;
};
void bar(const double& d) {
std::vector<Foo> fv;
fv.emplace_back(d);
}
Run Code Online (Sandbox Code Playgroud) 以下代码无法在gcc 5.3上编译,并出现编译器错误,原因是抱怨以某种方式调用了unique_ptr的副本构造函数。有人可以解释为什么会这样吗?
#include <iostream>
#include <memory>
#include <deque>
using Foo = std::deque<std::unique_ptr<int>>;
void foo() {
std::vector<Foo> a;
a.emplace_back(); // this fails to compile
}
Run Code Online (Sandbox Code Playgroud)
编译器错误的关键所在是:
gcc-4.9.2/include/c++/4.9.2/bits/stl_construct.h:75:7: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’ { ::new(static_cast<void*>(__p)) _T1(std::forward<_Args>(__args)...); }