小编αλε*_*λυτ的帖子

迭代器和标量对象之间的未定义行为有什么区别吗?

关于评估顺序的主题说,在C++ 17之前,以下代码会导致未定义的行为:

a[i] = i++;
Run Code Online (Sandbox Code Playgroud)

这是由于在评估赋值表达式的左右部分时未指定的顺序而发生的.

C++ 14标准1.9/15说:

如果对标量对象的副作用相对于同一标量对象的另一个副作用或使用相同标量对象的值进行的值计算未被排序,并且它们不可能是并发的(1.10),则行为未定义.

但是如果我们使用std::vector它的iterator对象而不是标量对象i呢?

std::vector<int> v = {1, 2};
auto it = v.begin();
*it = *it++;   // UB?
Run Code Online (Sandbox Code Playgroud)

是否存在未定义的行为(直到c ++ 17)?

c++ undefined-behavior language-lawyer c++11 c++14

11
推荐指数
1
解决办法
393
查看次数

与const引用关联的临时对象的生命周期(方法链接)

考虑以下代码snipet:

#include <iostream>

struct S {
    ~S() { std::cout << "dtor\n"; }
    const S& f(int i) const { std::cout << i << "\n"; return *this; }
};

int main() {
    const S& s = S(); 
    s.f(2);
}
Run Code Online (Sandbox Code Playgroud)

输出:

2
dtor
Run Code Online (Sandbox Code Playgroud)

即对象的生命周期通过引用扩展,这在Herb的文章中有所解释.

但是,如果我们只更改一行代码并写入:

const S& s = S().f(1);
Run Code Online (Sandbox Code Playgroud)

f(2)对已经被摧毁的物体的召唤:

输出:

1
dtor
2
Run Code Online (Sandbox Code Playgroud)

为什么会这样?是f()的返回值不是一个正确的类型'暂时性’的?

c++ reference lifetime

9
推荐指数
1
解决办法
402
查看次数

是否允许递归初始化数组?

我有以下代码片段:

int i[] = {42, i[0]};
Run Code Online (Sandbox Code Playgroud)

是允许这样的初始化还是导致未定义的行为?

三大编译器(GCC,铛,MSVC)给我42i[1].因此看起来合法,但我希望从这个案例的标准中看到一个引用.

c++ array-initialization language-lawyer

9
推荐指数
1
解决办法
238
查看次数

多种转换功能作为课堂上的“operator auto”

在下面的代码中

struct S {
    operator auto() { return 42; }
};
Run Code Online (Sandbox Code Playgroud)

operator auto等价于operator int因为实际类型是从文字中推导出来的,42而该类型是int. 如果我写42.5而不是42thenoperator auto将被解释operator double为显而易见的原因。但是当我同时使用两者时,所有三个主要编译器(gcc、clang、msvc)都出现编译器错误:

struct S {
    operator auto() { return 42; }
    operator auto() { return 42.5; }
};
Run Code Online (Sandbox Code Playgroud)

编译器之间的实际错误消息各不相同,但原因是相同的:“函数已经定义”。

我无法在标准中找到为什么operator auto不能在一个类中同时使用两者(具有不同的返回类型)。有人可以指出标准的条款,其中该组转换函数被认为是被禁止的吗?

c++ type-conversion language-lawyer auto

9
推荐指数
1
解决办法
137
查看次数

在= delete的含义中使用= default

以下代码编译得很好:

struct B { 
    B(int) {} 
};

struct D : B {
    D() = default;
};
Run Code Online (Sandbox Code Playgroud)

直到我必须创建一个类的实例D:

D d; // error: use of deleted function 'D::D()'
Run Code Online (Sandbox Code Playgroud)

没有任何理由(用例),以允许= default进行D的构造,当它的实际工作为= delete;

c++ default-constructor c++11

8
推荐指数
2
解决办法
273
查看次数

从 initializer_list 构造 string_views 的向量

我试图构建vectorstring_view距离Sinitializer_list< const char * >这对GCC 9效果不错,但更新至GCC 10后,在运行时崩溃。

#include <vector>
#include <string_view>
#include <cstdio>

int main()
{
    std::vector< std::string_view > const v { { "Before.", "Afterrrrrr." } };
    printf( "%s %zu\n", v[0].data(), v[0].length() );
    printf( "%s %zu\n", v[1].data(), v[1].length() );

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Clang 也处理代码,好吧,什么给出了?

链接:https : //godbolt.org/z/6s1c61

c++ gcc c++20

8
推荐指数
1
解决办法
160
查看次数

应该在带花括号的 return 语句中调用什么构造函数?

考虑以下代码:

struct NonMovable {
  NonMovable() = default;
  NonMovable(const NonMovable&) = default;
  NonMovable(NonMovable&&) = delete;
};

NonMovable f() {
  NonMovable nonMovable;
  return {nonMovable};
  //return NonMovable(nonMovable);
}

int main() {}
Run Code Online (Sandbox Code Playgroud)

GCC 和 Clang 编译该代码没有错误,即在使用大括号时调用了复制构造函数。但是 msvc 拒绝它https://godbolt.org/z/49onKj并出现错误:

error C2280: 'NonMovable::NonMovable(NonMovable &&)': attempting to reference a deleted function
Run Code Online (Sandbox Code Playgroud)

当我指定显式调用复制构造函数(因为nonMovable不是右值)时,mvsc 接受代码。

谁是对的?在return {var};那里的语句中应该调用什么类型的构造函数?

c++ language-lawyer c++17

8
推荐指数
1
解决办法
271
查看次数

函数声明必须可用,因为没有任何参数依赖于模板参数

以下代码在 trunk gcc 和 clang 中编译良好,但在 msvc for c++20 模式下编译失败:

template <typename T = int>
void f(void* ptr, T&& t = {}) {
    if (ptr) {
        f(nullptr);
    }
}
Run Code Online (Sandbox Code Playgroud)

与消息:

error C2672: 'f': no matching overloaded function found
note: could be 'void f(void *,T &&)'
note: 'void f(void *,T &&)': could not deduce template argument for 'T'
note: 'f': function declaration must be available as none of the arguments depend on a template parameter
Run Code Online (Sandbox Code Playgroud)

适用于 c++17 模式的 msvc,因为 …

c++ templates language-lawyer

8
推荐指数
1
解决办法
733
查看次数

'使用'声明为SFINAE

我可以使用SFINAE(或其他技术)进行using声明,而私有派生自模板类吗?为了更好地理解,请参阅以下代

#include <iostream>

struct S1 {
    void f() { std::cout << "S1::f\n"; }
};

struct S2 {
    void f() { std::cout << "S2::f\n"; }
    void g() { std::cout << "S2::g\n"; }
};

template <class T>
struct D : private T {
    using T::f;
    // using T::g; // need this only if T provides g() function
};

int main() {
    D<S1>().f(); // ok. Prints 'S1::f'
    D<S2>().f(); // ok. Prints 'S2::f' 
    D<S2>().g(); // fail. But wants to be ok and …
Run Code Online (Sandbox Code Playgroud)

c++ sfinae using-declaration private-inheritance

7
推荐指数
2
解决办法
337
查看次数

使用clang-format保留完整函数的短lambda用作中间参数

我想用clang-format格式化代码,并完整保留lambda用作中间函数参数:

void f()
{
    func(this, [this] { return false; }, this);
}
Run Code Online (Sandbox Code Playgroud)

我尝试用clang格式9.0进行的所有操作都将参数包装到下一行,即:

void f()
{
    func(
        this, [this] { return false; }, this);
}
Run Code Online (Sandbox Code Playgroud)

如果没有第一个或/和最后一个参数,则即使内置-style='WebKit'选项也可以提供所需的结果:

void f()
{
    func([this] { return false; }, this); // ok
    func(this, [this] { return false; }); // ok 
    func([this] { return false; });       // ok 
}
Run Code Online (Sandbox Code Playgroud)

自LLVM 8.0起,似乎有所更改(损坏),因为7.1可根据需要工作。

c++ lambda clang-format

7
推荐指数
1
解决办法
190
查看次数