C ++ 17 noexcept是函数类型的一部分。它还允许从noexcept函数指针到潜在地抛出函数指针的隐式转换。
void (*ptr_to_noexcept)() noexcept = nullptr;
void (*ptr_to_throwing)() = ptr_to_noexcept; // implicit conversion
Run Code Online (Sandbox Code Playgroud)
http://eel.is/c++draft/expr.static.cast#7说static_cast可以执行这种转换的逆过程。
void (*noexcept_again)() noexcept = static_cast<void(*)() noexcept>(ptr_to_throwing);
Run Code Online (Sandbox Code Playgroud)
不幸的是,GCC和clang都告诉我否则:https : //godbolt.org/z/TgrL7q
正确的方法是什么?是reinterpret_cast和C风格的投我唯一的选择吗?
我的目标是将类型的元素映射到相同类型的其他元素.假设它们是size_t为了简单起见.
std::map<size_t, size_t> myMapping;
Run Code Online (Sandbox Code Playgroud)
这样做,但如果我想跟随一堆这样的链接(它们都是相同的地图),每一步都是log(n)查找.
size_t k = /*whatever*/;
myMapping[myMapping[myMapping[k]]]; //3 * log(n)
Run Code Online (Sandbox Code Playgroud)
我想利用map迭代器保持有效的事实,并有一个映射将size_t映射到迭代器的映射.
typedef /*myMapTemplate*/::iterator map_iter;
std::map<size_t, map_iter> myMapping;
size_t k = /*whatever*/
map_iter entryPoint = myMapping.find(k);
entryPoint->second->second->first; //log(n) + 2 constant time operations
Run Code Online (Sandbox Code Playgroud)
我该怎么写这种类型?我知道复制会将迭代器保留在旧地图上并计划自己处理.
分配器无国籍意味着什么?我意识到std :: allocator是malloc的包装器,并且没有自己的状态.同时,malloc也有自己的簿记,所以可以说所有std :: allocator实例都使用单个状态.
如何在没有状态的情况下实现池分配器?如果不是分配器,什么会保持当前的内存状态?
有人可以在这种情况下正式定义哪个州意味着什么?
我试图利用这样一个事实,即插入和删除之后列表的迭代器仍然有效(除了刚刚删除的迭代器之外).这也是如此std::list<T>::end();
假设我尝试以下方法:
typedef std::list<int> list_int;
list_int myList;
list_int::iterator iter = myList.end();
myList.push_back(1);
myList.push_back(2);
myList.push_back(3);
if(iter == myList.end()) {
/* do things here */
} else {
/* do different things here */
/* I don't expect this branch to ever execute */
}
Run Code Online (Sandbox Code Playgroud)
This is important because elsewhere I might store a collection of iterators into this list, and I would test for validity by comparing against myList.end(). It's important that invalid iterators remain so even after insertions …
我的类继承自多个基类,其中之一是std::enable_shared_from_this. 必须是第一垒吗?
假设以下示例代码:
struct A { ~A(); };
struct B { ~B(); };
struct C : A, B, std::enable_shared_from_this<C> {};
std::make_shared<C>();
Run Code Online (Sandbox Code Playgroud)
当~A()与~B()运行,我可以肯定的是,当存储C生活仍然存在?
c++ inheritance multiple-inheritance c++11 enable-shared-from-this
我想开发一个针对现代流行 Linux 发行版的应用程序,该应用程序使用 GTK 作为其 UI,同时也使用 Vulkan API 来渲染 3D 模型。理想情况下,我想使用gtkmmGTK 的 C++ 包装器和 Vulkan C++ API。
我目前必须采取哪些方法才能做到这一点?
我知道我可以使用 SDL2 和其他类似的低级库获取 Vulkan 上下文,并且可以使用 GTK 获取 OpenGL 上下文。但我还没有找到结合这两种方法的资源。
首先,我不限于在任何特定的 Linux 发行版上进行开发或针对任何特定的 Linux 发行版。尽管任何关于为什么特定环境使这变得更容易或更困难的见解都是值得赞赏的。
编辑:
我知道这个问题:GtkGLArea 小部件 (GTK+) 的 Vulkan 等效项是什么?
然而,距离最近一次更新已经过去了好几个月。我的谷歌搜索并没有表明事态已经改变,但我希望被证明是错误的。此外,我故意更广泛地表达了我的问题。我不一定只想要一个GtkVulkanArea小部件。我想知道结合 Gtk 和 Vulkan 的任何有效方法。例如,是否可以在 SDL2 窗口中嵌入 Gtk 事件循环和小部件?反过来呢?再说一次,我的谷歌搜索并没有多大帮助,我希望对此主题有了解的人能够回答。
在一个线程内,steady_clock::now()保证返回单调递增的值。这如何与多线程观察到的内存排序和读取交互?
atomic<int> arg{0};
steady_clock::time_point a, b, c, d;
int e;
thread t1([&](){
a = steady_clock::now();
arg.store(1, memory_order_release);
b = steady_clock::now();
});
thread t2([&](){
c = steady_clock::now();
e = arg.load(memory_order_acquire);
d = steady_clock::now();
});
t1.join();
t2.join()
assert(a <= b);
assert(c <= d);
Run Code Online (Sandbox Code Playgroud)
这是重要的一点:
if (e) {
assert(a <= d);
} else {
assert(c <= b);
}
Run Code Online (Sandbox Code Playgroud)
这些断言会失败吗?或者我对获取释放内存顺序有什么误解?
以下主要是对我的代码示例的解释和详细说明。
线程t1写入原子arg。它也记录在当前时间之前,并在写入之后a和b分别。steady_clock保证a <= b。
线程t2从原子中读取arg并保存读入的值e …
C++17 添加了结构化绑定:
tuple<int, int, int> make_tuple();
int test() {
auto [a, b, c] = make_tuple();
return a | b | c;
}
Run Code Online (Sandbox Code Playgroud)
我的直觉是尝试将它们用作参数包。
template <size_t N>
auto make_tuple(); // returns tuple with N ints
template <size_t N>
int test() {
auto [...values] = make_tuple<N>();
return (0 | ... | values);
}
Run Code Online (Sandbox Code Playgroud)
唉,我不能这样做。为什么委员会排除了这样的功能?现在感觉不一致,因为 lambda 捕获可以包含参数包。
我知道委员会充满了聪明的创意人士,像我这样的想法一定有充分的理由被拒绝。那是什么原因?
C++ 中的常规goto尊重对象生命周期 - 即使用goto跳出块将为适当的局部变量运行析构函数。
start:
NonTrivial object;
if (again()) goto start; // will call object.~NonTrivial()
Run Code Online (Sandbox Code Playgroud)
使用标签作为值扩展时也是如此吗?
start:
NonTrivial object;
goto *(again() ? &&start : &&end);
end:
Run Code Online (Sandbox Code Playgroud)
GCC 很高兴地接受了这段代码,但似乎忽略了goto可能对object生命周期产生的任何影响。铿锵抱怨:
error: cannot jump from this indirect goto statement to one of its possible targets
note: possible target of indirect goto statement
note: jump exits scope of variable with non-trivial destructor
Run Code Online (Sandbox Code Playgroud)
查找对Compiler Explorer 的NonTrivial()调用以及~NonTrivial()在 Compiler Explorer 中的调用。
哪个编译器行为正确?一般来说,是否有可能支持这种间接分支并正确管理对象生存期和 RAII?
C++ 有虚函数,调用虚函数会在运行时在 vtable 中查找函数地址。
C++ 也有虚拟基。访问虚拟基的数据成员将在运行时查找虚函数表的偏移量。
为什么C++缺少虚拟数据成员?访问一个虚拟基时会在 vtable 中查找偏移量,但数据成员将由派生基提供
virtual void fun();
virtual int val;
void fun() override;
int val override;
Run Code Online (Sandbox Code Playgroud) 我最近升级到了新版本的 gcc/g++/gcov,现在 gcov 的行为很奇怪。新版本声称未涵盖旧版本中涵盖的某些代码行。我设法将我的代码减少到这个最小的示例。
#include <memory>
using namespace std;
struct S {};
int main() {
unique_ptr<S> s;
s = make_unique<S>();
}
Run Code Online (Sandbox Code Playgroud)
然后我使用 编译此文件g++ -O0 -Wall -Wextra -Werror --std=c++17 --coverage,运行结果a.out,然后运行gcov。
生成的.gcov文件包含:
-: 0:Runs:1
-: 1:#include <memory>
-: 2:using namespace std;
-: 3:struct S {};
-: 4:
1: 5:int main() {
#####: 6: unique_ptr<S> s;
1: 7: s = make_unique<S>();
1: 8:}
Run Code Online (Sandbox Code Playgroud)
这与 gcov 的旧版本不同,旧版本声称第 6 行被命中了 2 次。
为什么 gcov 认为第 6 行没有被覆盖?难道我做错了什么? …
什么是安全、便携、惯用的方式来使用std::vector.
std::vector<Foo> foos;
foos.emplace_back(1);
foos.emplace_back(2);
foos.reserve(10);
Run Code Online (Sandbox Code Playgroud)
此时foos,至少拥有8 * sizeof(Foo)从 开始的未初始化的备用内存foos.data() + foos.size()。让这些内存浪费掉似乎非常低效。在Foo通过附加到用对象填充它之前,如何将此空闲容量用作暂存空间或用于其他目的foos?在不调用任何未定义行为的情况下执行此操作的正确方法是什么?
可能重复:
C++参考,更改引用的变量
我知道c ++中的引用只是在你使用它们时会被解除引用的指针.这个问题是关于如何访问底层指针并进行更改.
考虑以下代码:
int x;
int& x_ref = x; //now equivalent to x
int* x_ptr = &x; //stores address of x
int* x_ref_ptr = &x_ref; //ALSO stores address of x
int&* x_ref_ptr_ref = ???; //what would this mean?
Run Code Online (Sandbox Code Playgroud)
我正在尝试更改初始化后参考点的位置.我不关心类型安全或正确的做法.c ++语言是否有任何工具可以让我实现这一目标?