小编Afs*_*hin的帖子

std::size_t 是不同的类型吗?

C++ 标准提到了这一点std::size_t

该类型size_t实现定义的无符号整数类型,它足够大以包含任何对象的字节大小 ([expr.sizeof])。

现在我的问题是,这种类型是否与其他 unsigned int 类型不同。我的意思是,我是否应该能够有这样的重载:

void myfunc(std::uint16_t) {}
void myfunc(std::uint32_t) {}
void myfunc(std::uint64_t) {}
void myfunc(std::size_t) {}
Run Code Online (Sandbox Code Playgroud)

因为如果它是一个不同的类型,我应该能够拥有这些重载,而如果不是,我应该得到重新定义错误。我总是认为这std::size_t应该是一个不同的类型,但我目前收到重新定义错误,这意味着它不是(至少在 GCC 和 Clang 中)

我问这个问题的原因是我想知道我是否对不同的 unsigned int 大小重载了一个函数,我是否可以安全地假设其中一个将被调用std::size_t或不被调用。

c++ overloading size-t language-lawyer

27
推荐指数
2
解决办法
2437
查看次数

C++中`std :: sort`比较器的不同类型

当我们提供比较器函数时std::sort,我们使用以下重载:

template< class RandomIt, class Compare >
void sort( RandomIt first, RandomIt last, Compare comp );
Run Code Online (Sandbox Code Playgroud)

其中比较器函数std::sort应具有以下语法:

bool cmp(const Type1 &a, const Type2 &b);
Run Code Online (Sandbox Code Playgroud)

但正如你所看到的a,b可能有不同的类型.cppreference说:

类型Type1Type2必须使得类型的对象RandomIt 可以被解除引用,然后隐式转换为它们两者.

但是当我们尝试对它进行排序时,我仍然无法准确理解我们如何在单个数组中有两种不同的类型.

是否有人可以为std::sort比较器功能提供不同类型的小例子?

c++

21
推荐指数
3
解决办法
2066
查看次数

std::atomic 等待操作如何工作?

从 C++20 开始,std::atomicwait()and notify_one()/notify_all()操作。但我不明白它们到底是如何工作的。cppreference 说

执行原子等待操作。其行为就像重复执行以下步骤:

  • 将 this->load(order) 的值表示与旧的值表示进行比较。
    • 如果它们相等,则阻塞直到*this收到notify_one()或notify_all()通知,或者线程被虚假地解除阻塞。
    • 否则,返回。

仅当值发生更改时,这些函数才保证返回,即使底层实现虚假地解除阻塞。

我不太明白这两个部分是如何相互关联的。这是否意味着如果值没有改变,那么即使我使用notify_one()/notify_all()方法,该函数也不会返回?这意味着该操作在某种程度上等于以下伪代码?

while (*this == val) {
    // block thread
}
Run Code Online (Sandbox Code Playgroud)

c++ c++20

13
推荐指数
1
解决办法
1648
查看次数

为什么没有按预期找到这个朋友方法?

当我有一小段这样的代码时:

#include <iostream>

class A {
public:
    friend inline std::ostream& operator<<(std::ostream& os, const A&);
};

inline std::ostream& operator<<(std::ostream& os, const A&) {
    os << "Called\n";
    return os;
}

class B {
public:
    operator A() { return A(); }
};

int main()
{
    A a;
    std::cout << a;
    B b;
    std::cout << b;
}
Run Code Online (Sandbox Code Playgroud)

theoperator<<aand都调用了两次b,因为btype 有一个隐式用户转换运算符A。但是当我将代码修改为这样时,我感到很惊讶:

#include <iostream>

class A {
public:
    friend std::ostream& operator<<(std::ostream& os, const A&) {
        os << …
Run Code Online (Sandbox Code Playgroud)

c++

10
推荐指数
1
解决办法
269
查看次数

在 libc++ 中使用 double 调用 std::from_chars 时出现编译错误

我有一个小代码如下:

int main() {
    double d;
    const char* str = "26.50";
    std::from_chars(str, str + strlen(str), d);
    std::cout << d;
}
Run Code Online (Sandbox Code Playgroud)

此代码在 libstdc++ 中按预期工作,但在 libc++ 12.0.0 中失败并出现以下错误:

int main() {
    double d;
    const char* str = "26.50";
    std::from_chars(str, str + strlen(str), d);
    std::cout << d;
}
Run Code Online (Sandbox Code Playgroud)

这是 libc++ 的错误吗?或者我错过了什么?我应该说,如果我将数据类型从 更改为 ,这段代码就可以double工作int

c++ libc++

10
推荐指数
0
解决办法
2086
查看次数

通过函数设置内部时,didSet如何再次调用?

据我所知和这个线程中提到的,如果我在其didSet观察者中设置属性值,它不应该再次触发观察者.好的,然后我写了一段这样的代码:

class B {
    var i = 0 {
        didSet {
            print("didSet called")
            self.i += 1
        }
    }
}

var y = B()
y.i = 2
print(y.i)
Run Code Online (Sandbox Code Playgroud)

此代码按预期打印"didSet called"3输出.但我对此代码做了一些小改动,如下所示:

class B {
    var i = 0 {
        didSet {
            print("didSet called")
            doit(val: self)
        }
    }

    func doit(val: B) {
        val.i += 1
    }
}

var y = B()
y.i = 2
print(y.i)
Run Code Online (Sandbox Code Playgroud)

但现在它陷入无限循环打印"didSet called".为什么如果我通过函数参数传递给内部didSet变量的值,它会didSet再次触发吗?由于传递的对象应该引用同一个对象,我不知道为什么会发生这种情况.我测试过,如果我通过闭包didSet …

swift

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

Clang优化函数中的“ ror”指令,但内联函数时不优化

我在clang优化中发现了一个奇怪的错误。这是代码:

#include <iostream>

unsigned int rot2(unsigned int a, size_t k) {
    return (a >> k) | (a << (sizeof(unsigned int) * 8 - k));
}

int main() {
    unsigned int x;
    std::cin >> x;
    auto n = rot2(x, 5);
    std::cout << n;
}
Run Code Online (Sandbox Code Playgroud)

这是为带-O3选项的clang 8.0.0和9.0.0生成的程序集(来自godbolt):

rot2(unsigned int, unsigned long):                              # @rot2(unsigned int, unsigned long)
        mov     rcx, rsi
        mov     eax, edi
        ror     eax, cl
        ret
main:                                   # @main
        push    rax
        lea     rsi, [rsp + 4]
        mov     edi, offset std::cin …
Run Code Online (Sandbox Code Playgroud)

clang clang++

7
推荐指数
0
解决办法
70
查看次数

奇怪的类型推导

今天我看到了一个非常奇怪的类型推导。这是代码:

unsigned int y = 15;
int k = 5;
auto t = k - y / 2;
Run Code Online (Sandbox Code Playgroud)

由于kis int,我认为该类型也t应该是int。但令我惊讶的是,它的类型是unsigned int. 我找不到为什么类型被推断为unsigned int. 知道为什么吗?

c++ integer expression implicit-conversion

6
推荐指数
1
解决办法
69
查看次数

没有优化的清零内存

如您所知,如果稍后不访问memset()内存,我们不能将其用于清零,因为它可能会被编译器优化。我看到了一个建议,在CPP参考,我们可以用一个指针来解决这个问题。现在这是我的问题:std::fillvolatile

  1. 这个语句是否意味着如果指针不是volatilestd::fill也可以优化?
  2. 例如,我们如何获得指向容器的 volatile 指针vector?这样的东西有用吗?
vector<int> v;
volatile auto ptr = v.data();
Run Code Online (Sandbox Code Playgroud)

c++

5
推荐指数
1
解决办法
103
查看次数

我需要编写第二个 SFINAE 构造函数吗?

当参数包中的所有类型都不同时,我想激活带有参数包的类。我编写了一个像这样的小辅助函数,它可以正常工作:

template<typename T, typename... Ts>
constexpr bool has_duplicate_types() {
    if constexpr (sizeof...(Ts) == 0)
        return false;
    else
        return ((std::is_same_v<std::decay_t<T>, std::decay_t<Ts>> || ...) || has_duplicate_types<Ts...>());
}
Run Code Online (Sandbox Code Playgroud)

当我尝试使用 SFINAE 激活我的课程时,我尝试了几种方法,有效的方法是:

template<typename T, typename dummy = void, typename... Ts>
struct XYZ_imp {
    XYZ_imp() {
        std::cout << "ok\n";
    }
};

template<typename T, typename... Ts>
struct XYZ_imp<T, std::enable_if_t<has_duplicate_types<T, Ts...>()>, Ts...> {
    XYZ_imp() = delete;
};

template<typename T, typename... Ts>
using XYZ = XYZ_imp<T, void, Ts...>;
Run Code Online (Sandbox Code Playgroud)

但正如您所看到的,代码太多了。但是当我尝试这样写时:

template<typename T, typename... Ts>
struct XYZ {
    template<typename U …
Run Code Online (Sandbox Code Playgroud)

c++ sfinae

5
推荐指数
1
解决办法
85
查看次数