标签: c++20

当“operator <=>”就足够了时,为什么我必须提供“operator ==”?

#include <compare>

struct A
{
    int n;

    auto operator<=>(A const& other) const
    {
        if (n < other.n)
        {
            return std::strong_ordering::less;
        }
        else if (n > other.n)
        {
            return std::strong_ordering::greater;
        }
        else
        {
            return std::strong_ordering::equal;
        }
    }

    // compile error if the following code is commented out.
    // bool operator==(A const& other) const
    // { return n == other.n; }
};

int main()
{   
    A{} == A{};
}
Run Code Online (Sandbox Code Playgroud)

在线演示

为什么我必须 operator == 足够的时候提供operator <=>

c++ language-design language-lawyer spaceship-operator c++20

52
推荐指数
4
解决办法
5074
查看次数

三向比较运算符与减法有何不同?

<=>在C++ 20中有一个新的比较运算符.但是我认为在大多数情况下,简单的减法效果很好:

int my_strcmp(const char *a, const char *b) {
    while (*a == *b && *a != 0 && *b != 0) {
        a++, b++;
    }
    // Version 1
    return *a - *b;
    // Version 2
    return *a <=> *b;
    // Version 3
    return ((*a > *b) - (*a < *b));
}
Run Code Online (Sandbox Code Playgroud)

它们具有相同的效果.我无法理解其中的差异.

c++ comparison-operators spaceship-operator c++20

51
推荐指数
3
解决办法
7480
查看次数

在现代C++中是否可以将字符串文字作为参数传递给C++模板?

是否可以在"现代C++"(C++ 17或更高版本)中将字符串文字作为参数传递给C++模板?

我意识到你可以用构造函数参数做到这一点; 我只是认为将它作为模板参数更方便,而不是深埋在cpp文件中.如果这可能是现代C++的一个新功能,我很好奇.请参阅下面的伪代码我正在尝试做的事情:

伪代码示例:

// Header File /////////////////////////
template<constexpr string Name>
class ModuleBase {
public:
    ModuleBase();
    string name;
};

class xyz : ModuleBase<"xyz"> {
public:
    xyz();
};

// Cpp File //////////////////////////
template<string_literal Name>
ModuleBase<Name>::ModuleBase() {
    name = Name;
}

xyz::xyz() : ModuleBase() {

}
Run Code Online (Sandbox Code Playgroud)

c++ c++17 c++20

50
推荐指数
1
解决办法
3468
查看次数

c++20 [[no_unique_address]] 中的新特性是什么?

我已经多次阅读了新的 c++20 特性no_unique_address,我希望有人能用一个比下面这个来自 c++ 参考的例子更好的例子来解释和说明。

说明 适用于在非位域的非静态数据成员的声明中声明的名称。

指示此数据成员不需要具有与其类的所有其他非静态数据成员不同的地址。这意味着如果成员具有空类型(例如无状态分配器),编译器可能会优化它以不占用空间,就像它是一个空基一样。如果该成员不为空,则其中的任何尾部填充也可以重新用于存储其他数据成员。

#include <iostream>
 
struct Empty {}; // empty class
 
struct X {
    int i;
    Empty e;
};
 
struct Y {
    int i;
    [[no_unique_address]] Empty e;
};
 
struct Z {
    char c;
    [[no_unique_address]] Empty e1, e2;
};
 
struct W {
    char c[2];
    [[no_unique_address]] Empty e1, e2;
};
 
int main()
{
    // e1 and e2 cannot share the same address because they have the
    // same type, even though they are marked with …
Run Code Online (Sandbox Code Playgroud)

c++ attributes c++20

50
推荐指数
3
解决办法
4692
查看次数

为什么unique_ptr 在C++20 中不是equality_comparable_with nullptr_t?

使用 C++20'sconcept我注意到这std::unique_ptr似乎无法满足这个std::equality_comparable_with<std::nullptr_t,...>概念。从std::unique_ptr的定义来看,它应该在 C++20 中实现以下内容:

template<class T1, class D1, class T2, class D2>
bool operator==(const unique_ptr<T1, D1>& x, const unique_ptr<T2, D2>& y);

template <class T, class D>
bool operator==(const unique_ptr<T, D>& x, std::nullptr_t) noexcept;
Run Code Online (Sandbox Code Playgroud)

这个要求应该实现对称比较nullptr——根据我的理解,这足以满足equality_comparable_with.

奇怪的是,这个问题似乎在所有主要编译器上都是一致的。以下代码被 Clang、GCC 和 MSVC 拒绝:

// fails on all three compilers
static_assert(std::equality_comparable_with<std::unique_ptr<int>,std::nullptr_t>);
Run Code Online (Sandbox Code Playgroud)

Try Online

然而,同样的断言与std::shared_ptr被接受:

// succeeds on all three compilers
static_assert(std::equality_comparable_with<std::shared_ptr<int>,std::nullptr_t>);
Run Code Online (Sandbox Code Playgroud)

Try Online

除非我误解了什么,否则这似乎是一个错误。我的问题是这是否是三个编译器实现中的巧合错误,还是 C++20 标准中的缺陷?

注意:如果这恰好是一个缺陷,我会标记这个

c++ language-lawyer c++-concepts c++20

50
推荐指数
1
解决办法
2136
查看次数

为什么双重否定会改变 C++ 概念的价值?

我的一个朋友向我展示了一个带有概念的 C++20 程序,这让我感到困惑:

struct A { static constexpr bool a = true; };

template <typename T>
concept C = T::a || T::b;

template <typename T>
concept D = !!(T::a || T::b);

static_assert( C<A> );
static_assert( !D<A> );
Run Code Online (Sandbox Code Playgroud)

它被所有编译器接受:https : //gcc.godbolt.org/z/e67qKoqce

这里的概念与概念D相同C,唯一的区别是双重否定运算符!!,乍一看不会改变概念值。仍然对于 struct 来说,A这个概念C是正确的,而这个概念D是错误的。

你能解释一下为什么会这样吗?

c++ language-lawyer c++-concepts c++20

49
推荐指数
2
解决办法
2231
查看次数

为什么在 C++20 中使用 `std::bind_front` 而不是 lambdas?

正如在一个类似措辞的问题中提到的(为什么在 c++14 中使用 bind over lambdas?)答案是 - 没有理由(并且还提到为什么使用 lambdas 会更好)。

我的问题是 - 如果在 C++14 中不再有理由使用绑定,为什么标准委员会认为有必要std::bind_front在 C++20 中添加?

它现在比 lambda 有什么新优势吗?

c++ lambda stdbind c++20 bind-front

48
推荐指数
2
解决办法
3121
查看次数

如何在 g++ 中使用 C++ 20

我正在尝试访问std::popcount,但似乎它只存在于 C++ 20 中

当我尝试使用 进行编译时g++ -std=c++20 main.cpp,它说g++: error: unrecognized command line option '-std=c++20'; did you mean '-std=c++03'

如何告诉 g++ 使用 c++ 20?

我使用的是Ubuntu 18.04

c++ g++ c++20

46
推荐指数
3
解决办法
12万
查看次数

为什么在C ++ 20中std :: move没有[[nodiscard]]?

我最近阅读了[[nodiscard]]C ++ 17,据我了解,它是一项新功能(按合同设计吗?),它迫使您使用返回值。对于有争议的函数std::launder(从C ++ 20开始不丢弃),这是有意义的,但是我想知道为什么std::move在C ++ 17/20 中没有这样定义。您知道很好的理由还是因为C ++ 20尚未完成?

c++ language-lawyer c++17 c++20

45
推荐指数
2
解决办法
1869
查看次数

C++20 是否取消了类成员按升序排列的要求?

在 C++17 中有规范文本 [class.mem]/17:

分配具有相同访问控制(第 14 条)的(非联合)类的非静态数据成员,以便后面的成员在类对象中具有更高的地址。具有不同访问控制的非静态数据成员的分配顺序未指定。

还有 [class.mem]/24:

如果标准布局类对象具有任何非静态数据成员,则其地址与其第一个非静态数据成员的地址相同

这里有两个例子:

struct A { int x, y, z; } a;
struct F { public: int p; private: int q; public: int r; } f;
Run Code Online (Sandbox Code Playgroud)

根据上述标准文本,C++17 保证&a.x < &a.y&a.y < &a.z、 和&f.p < &f.r (但不保证&f.p < &f.q,因为F不是标准布局,所以 class.mem/24 不适用)。


但是,在 C++20 最终工作草案 N4860 中,根据CWG 2404进行了更改。[class.mem]/17 已经变成了 Note。然而,注释在 ISO 标准中是非规范的(意味着编译器供应商可以忽略它们)。我找不到任何其他可能适用的文本。

我的问题是: C++20 是否仍然在某处指定(规范地)保证&a.y < &a.z和/或&f.p < &f.r?或者编译器现在是否有权在所有情况下重新排序类成员,标准布局类的第一个子对象除外? …

c++ class language-lawyer standard-layout c++20

45
推荐指数
1
解决办法
1603
查看次数