我知道这听起来像是一个奇怪的问题,但我很好奇。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) 我有一个元组,我想对传递索引处的元组中的类型执行某些操作(在示例中,打印默认值)。目前,我让它调用一个函数来增加模板化索引,直到它等于运行时索引。由于这种方法会降低性能,有更好的方法吗?
这是示例的代码:
#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.
我想引入在编译时进行错误检查的强类型。对于我的 chrono 类型,我注意到当基础类型从 变为 时,文字会默默地缩小int64_t,int32_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) 在下面的代码中,
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) 使用 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) 下面的函数尝试创建一个位板,其中设置的位位于第 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编译器
出于调试目的,我正在编写一个函数,该函数迭代任何类型的可选变量向量以检查哪些变量已初始化,但对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) 我需要将元素存储在连续的容器中,例如std::vector. 问题是容器需要支持插入或两者都支持int和std::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++ 不允许获取静态数据成员的地址?在这种情况下,静态成员的存储空间是如何分配的?
下面的最小程序演示了这个问题。
#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++中什么效率更高?
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)
?