小编Dai*_*ner的帖子

为什么unique_ptr有两个函数reset和operator=,它们做类似的事情但不重载?

我知道这听起来像是一个奇怪的问题,但我很好奇。unique_ptr运算符=将右值引用作为参数并调用reset(r.release()),然后移动自定义删除器。最后,运算符返回*this。喜欢:

// this is pseudo code
unique_ptr& operator=(unique_ptr&& r)
{
  reset(r.release());  // Change managed pointer
  setDeleter(r.getDeleter());
  return *this;
}
Run Code Online (Sandbox Code Playgroud)

unique_ptr重置函数以左值原始指针作为参数,并在更改其管理的指针后删除旧指针。在两者之间,它们具有相同的更改所管理的指针的行为。该行为由相同的 reset() 函数处理。这两个函数做类似的事情,除了参数的差异之外,我想不出一个单独的用例,所以我想知道是否可以重载它们。喜欢:

// this is pseudo code
unique_ptr& operator=(unique_ptr&& r) // or a function named reset
{
  changeManagedPtr(r.release()); // and delete old pointer
  setDeleter(r.getDeleter());
  return *this;
}

unique_ptr& operator=(pointer p) // or a function named reset
{
  changeManagedPtr(p); // and delete old pointer
  // setDeleter(r.getDeleter()); there is no deleter in p
  return *this;
}
Run Code Online (Sandbox Code Playgroud)

为什么这两个函数要分开编写而不是作为同名的重载函数呢?如果可能的话,是不是可以使用像这样不那么混乱的东西:

unique_ptr<int> uniqPtrInt, dest;
int* rawPtrInt …
Run Code Online (Sandbox Code Playgroud)

c++ smart-pointers unique-ptr c++11 c++14

2
推荐指数
1
解决办法
410
查看次数

将运行时 size_t 变量传递到模板参数中

我有一个元组,我想对传递索引处的元组中的类型执行某些操作(在示例中,打印默认值)。目前,我让它调用一个函数来增加模板化索引,直到它等于运行时索引。由于这种方法会降低性能,有更好的方法吗?

这是示例的代码:

#include <tuple>
#include <vector>
#include <string>
#include <iostream>

using tup = std::tuple<int, std::string, double, int>;

template <size_t Index = 0>
void constexpr PrintDefaultAtTupleIndex(size_t i)
{
    if (Index == i)
    {
        std::cout << "\"" << std::tuple_element_t<Index, tup>() << "\"" << std::endl;
        return;
    }
    if constexpr (Index + 1 < std::tuple_size_v<tup>)
        return PrintDefaultAtTupleIndex<Index + 1>(i);
}

int main()
{
    std::vector<size_t> indexs = {0, 3, 8, 2, 1};
    for (size_t &i : indexs)
    {
        PrintDefaultAtTupleIndex(i);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是真实代码的简化示例。真正的代码是元组的格式化程序。我试图有一种方法来指定它的打印顺序,所以我让它将索引存储在元组和格式化程序(input_formats)中,然后我通过它们调用OutputInputFormat.

https://pastebin.com/tvc13dX2

c++ templates

2
推荐指数
1
解决办法
172
查看次数

Constexpr 构造函数在编译时不求值

我想引入在编译时进行错误检查的强类型。对于我的 chrono 类型,我注意到当基础类型从 变为 时,文字会默默地缩小int64_tint32_t从而导致溢出。所以我引入了显式检查。

delay_t {10s}然而,即使对于常量参数(例如无法表示的 ),在编译时也不会检查此检查。

#include <chrono>
#include <cstdint>
#include <stdexcept>


struct delay_t {
    std::chrono::duration<int32_t, std::nano> value {};

    constexpr explicit delay_t(std::chrono::duration<int64_t, std::nano> delay) 
        : value {delay} 
    {
        if (value != delay) {
            throw std::runtime_error("delay cannot be represented.");
        }
    };
};

auto foo(delay_t delay) -> void {}

auto main() -> int {
    using namespace std::chrono_literals;

    foo(delay_t {10s});  // here I want a compile time error, 
                         // but I get a runtime error.

    return …
Run Code Online (Sandbox Code Playgroud)

c++ constexpr c++11

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

为什么 int&amp; 作为函数参数使用 QWORD(8 字节)内存,而 int 参数使用 DWORD

在下面的代码中,

int firstFunction(int& refParam)
{
    std::cout << "Type of refParam is: " << typeid(refParam).name() << '\n';
    return refParam;
}

int secondFunction(int param)
{
    std::cout << "Type of param is: " << typeid(param).name() << '\n';
    return param;
}

int main()
{
    int firstVar{ 1 };
    int secondVar{ firstFunction(firstVar) };
    int thirdVar{ secondFunction(firstVar) };
}
Run Code Online (Sandbox Code Playgroud)

控制台输出是

int
int
Run Code Online (Sandbox Code Playgroud)

当我检查Godbolt 链接中的汇编代码时。

firstFunction(int&):
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], rdi
        mov     rax, QWORD PTR [rbp-8]
        mov     eax, DWORD PTR [rax] …
Run Code Online (Sandbox Code Playgroud)

c++ assembly gcc reference x86-64

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

使用 constexpr 变量作为 case 标签

使用 constexpr 变量作为 case 标签是否正确?

#include <iostream>

int main() {
    constexpr int x = 5;

    int y = 4;

    switch (y) {
        case x - 1:
            std::cout << "case " << x << std::endl;

            break;

        case 20:
            std::cout << "case 20" << std::endl;

            break;

        default:
            std::cout << "case default" << std::endl;

            break;
    }
}
Run Code Online (Sandbox Code Playgroud)

c++ switch-statement constexpr c++17

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

在 cpp 中将 uint64_t 位移位 uint16_t 时出现奇怪的错误

下面的函数尝试创建一个位板,其中设置的位位于第 N 个位置,通过位移 0x1 N 次来达到所需的结果。N 由 uint16_t 中的第 1-6 个最低有效位给出。然后将其屏蔽以隔离 6 个 lsb。

uint64_t endSquareFinder(uint16_t a){
    a &= (0x003f);
    return 0x0000000000000001 << a;
}
Run Code Online (Sandbox Code Playgroud)

所有输入均有效,除了 a = 0x001f 时,函数的输出为 0xffffffff80000000 而不是 0x0000000080000000。这对我来说非常奇怪。

gdb编译器

c++ binary hex chess bitboard

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

std::Optional&lt;std::any&gt; 和 has_value() 之间的交互

出于调试目的,我正在编写一个函数,该函数迭代任何类型的可选变量向量以检查哪些变量已初始化,但对has_value()所有变量的检查都返回了true,尽管尚未为其中某些变量分配任何值。

我很感激任何帮助指出我的误解,因为我是 C++ 新手。代码如下。请注意,当注释行被取消注释时,if 语句会发现该变量没有值。

#include <iostream>
#include <optional>
#include <any>

bool SimpleCheck(std::vector<std::optional<std::any>> toCheck)
{
    bool res = false;
    for (int i = 0; i < toCheck.size(); ++i)
    {
        // toCheck[i] = std::nullopt;
        if (!toCheck[i].has_value())
        {
            std::cout << "item at index " << i << " had no value\n";
            res = true;
        }
    }
    return res;
}

int main() 
{
    std::optional<int> i = 5;
    std::optional<std::string> str;
    std::optional<double> doub = std::nullopt;
    bool check = SimpleCheck({i, str, doub}); …
Run Code Online (Sandbox Code Playgroud)

c++ c++17 stdany stdoptional

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

如何在向量中存储整数和字符串?

我需要将元素存储在连续的容器中,例如std::vector. 问题是容器需要支持插入或两者都支持intstd::string

这在 C++ 中似乎很难做到,因为它是一种强类型语言。我想做一些类似的事情

std::vector<std::pair<int, std::string>> container;
Run Code Online (Sandbox Code Playgroud)

或者

struct custom_struct {
  int val;
  std::string;
  bool is_val;    // true if integer and false if string
};
std::vector<custom_struct> container;
Run Code Online (Sandbox Code Playgroud)

但这似乎都不是一个很好的选择。第一个的问题是,我不知道如何在该对表示整数还是字符串之间切换,因此为什么我想出了第二种方法,尽管第二种方法不是很优雅,因为我必须重复键入检查使用is_val

我可以在 C++ 中考虑其他方法吗?

c++ types vector

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

静态数据成员的地址

为什么当数据成员在类内初始化且没有类外定义时,C++ 不允许获取静态数据成员的地址?在这种情况下,静态成员的存储空间是如何分配的?

下面的最小程序演示了这个问题。

#include <iostream>

class Test {
public:
    static const int a = 99;   // how is the storage allocated for Test::a??
};

// const int Test::a;

int main() {
    std::cout << Test::a << '\n';  // OK, print 99
    const int* ptr = &Test::a;     // Linker error, undefined reference to Test::a
}
Run Code Online (Sandbox Code Playgroud)

如果我取消注释该行const int Test::a,那么程序就可以正常工作。

c++ static-members

0
推荐指数
1
解决办法
149
查看次数

额外的 std::map::contains 调用与处理异常?

c++中什么效率更高?

if (my_map.contains(my_key)) return my_map.at(my_key);
Run Code Online (Sandbox Code Playgroud)

或者

try { return my_map.at(my_key); } catch (std::out_of_range e) { ... }
Run Code Online (Sandbox Code Playgroud)

c++ stl stdmap c++20

0
推荐指数
1
解决办法
72
查看次数