我倾向于在我的C++代码中添加许多断言,以便在不影响发布版本性能的情况下简化调试.现在,assert是一个纯C宏设计,没有考虑到C++机制.
另一方面std::logic_error,C++定义了在程序逻辑中存在错误(因此名称)的情况下抛出的内容.抛出一个实例可能只是一个完美的,更多的C++替代品assert.
问题是,assert并且abort两者都立即终止程序而不调用析构函数,因此跳过清理,而手动抛出异常会增加不必要的运行时成本.解决这个问题的一种方法是创建一个自己的断言宏SAFE_ASSERT,它就像C对应物一样工作,但在失败时抛出异常.
我可以想到关于这个问题的三种看法:
#define在C++中使用s同样糟糕.NDEBUG这种情况在发布版本中永远不会发生.捕获是不必要的,并公开内部代码的实现细节main().这个问题有明确的答案吗?有专业的参考吗?
编辑:跳过析构函数当然没有未定义的行为.
我试图迭代地导航递归数据结构,以便在某个位置插入元素.根据我的有限理解,这意味着对结构的根进行可变引用,并通过对其跟随者的引用连续替换它:
type Link = Option<Box<Node>>;
struct Node {
next: Link
}
struct Recursive {
root: Link
}
impl Recursive {
fn back(&mut self) -> &mut Link {
let mut anchor = &mut self.root;
while let Some(ref mut node) = *anchor {
anchor = &mut node.next;
}
anchor
}
}
Run Code Online (Sandbox Code Playgroud)
但是,这失败了:
error[E0499]: cannot borrow `anchor.0` as mutable more than once at a time
--> src/main.rs:14:24
|
14 | while let Some(ref mut node) = *anchor {
| ^^^^^^^^^^^^
| | …Run Code Online (Sandbox Code Playgroud) 我可以使用模板函数捕获数组及其(编译时)大小,如下所示:
template<int N>
void foo(const int (&)[N]) {
std::cout << "foo(const int (&)[N])\n";
}
Run Code Online (Sandbox Code Playgroud)
但是,我想重载foo以允许指向const的指针,以便在数组类型上调用函数时使用第一个重载,而在直接调用指针时调用第二个重载.
void foo(const int *) {
std::cout << "foo(const int *)\n";
}
int main() {
int a[1] = { 0 };
foo(a);
const int b[1] = { 0 };
foo(b);
}
Run Code Online (Sandbox Code Playgroud)
这里,第一个重载被调用a,第二个过载被调用b.
我的猜测是,a编译器必须执行转换为const,这意味着它foo(const int *)不是一个完美的匹配,但我已经迷失了为什么这甚至不是一个模糊的函数调用.
如何更改代码,以便在两种情况下都调用第一个重载?
在下面的代码中,wrapper<T>声明了一个包含a 的对象movable<T>,其中T是一个不完整的类型.构造析构函数movable是为了在没有完全知识的情况下无法实例化T,但是wrapper析构函数只是向前声明,这意味着如果~movable()在定义的时候实例化它就足够了~wrapper().
#include <utility>
template<class T>
struct movable {
movable() noexcept = default;
~movable() noexcept { (void) sizeof(T); }
movable(const movable&) noexcept = delete;
movable(movable &&) noexcept = default;
};
template<class T>
class wrapper {
public:
movable<T> m;
wrapper() noexcept = default;
wrapper(wrapper &&) noexcept = default;
~wrapper();
};
struct incomplete;
int main() {
/* extern */ wrapper<incomplete> original;
wrapper<incomplete> copy(std::move(original));
}
Run Code Online (Sandbox Code Playgroud)
但是, …
我想用所谓的“标题栏”更改 GTK+3 窗口上关闭按钮的样式,其中窗口在没有装饰的情况下呈现,GTK 组成标题栏和小部件。
“X”关闭按钮是什么类型的元素,它属于哪些 CSS 类(如果有)?

请注意,这不是窗口管理器主题的一部分,而是实际由 GTK+ 绘制的。
在CMake中,C++编译器的标志可以通过各种方式受到影响:CMAKE_CXX_FLAGS手动设置,使用add_definitions(),强制某个C++标准等等.
为了使用不同的规则(在我的情况下是预编译的头)在同一个项目中编译目标,我需要重现用于编译add_executable()由此目录中的命令添加的文件的确切命令.
读取CMAKE_CXX_FLAGS只返回显式设置的值,CMAKE_CXX_FLAGS_DEBUG兄弟姐妹只列出默认的Debug/Release选项.有一个特殊的功能,检索标志从add_definitions()和add_compiler_options(),但没有似乎能够返回最终的命令行.
如何将传递给编译器的所有标志都放入CMake变量?
看看这段C++代码:
class Foo
{
int a;
public: Foo(int b): a(a) {}
};
Run Code Online (Sandbox Code Playgroud)
显然,开发商意味着初始化a与b而非a本身,这是一个相当困难的现场错误.
Clang ++会警告这个可能的错误,而GCC不会,即使启用了其他警告:
$ clang++ -c init.cpp
init.cpp:5:27: warning: field is uninitialized when used here [-Wuninitialized]
public: Foo(int b): a(a) {}
^
$ g++ -Wall -Wuninitialized -Winit-self -c init.cpp
$
Run Code Online (Sandbox Code Playgroud)
有没有机会为g ++启用相同的输出?
虚拟基类在最派生的类中初始化,所以我的猜测是继承基类的构造函数也应该工作:
struct base {
base(int) {}
};
struct derived: virtual base {
using base::base;
};
derived d(0);
Run Code Online (Sandbox Code Playgroud)
但是,这无法使用GCC 5.2.0进行编译,GCC 5.2.0尝试查找base::base(),但与Clang 3.6.2一起正常工作.这是GCC中的错误吗?
我有一个foo定义如下的函数:
fn foo<'a>(a: &'a i32, b: &i32) -> &'a i32 { a }
Run Code Online (Sandbox Code Playgroud)
我想在结构中存储指向该函数的指针:
struct S {
f: fn(a: &i32, b: &i32) -> &i32,
}
Run Code Online (Sandbox Code Playgroud)
因为有两个输入生命周期,所以无法推断结果生命周期:
error[E0106]: missing lifetime specifier
|
2 | f: fn(a: &i32, b: &i32) -> &i32,
| ^ expected lifetime parameter
|
= help: this function's return type contains a borrowed value,
but the signature does not say whether it is borrowed from a or b
Run Code Online (Sandbox Code Playgroud)
当我问编译器foo的类型时,它也不是很有帮助:
let () = foo;
Run Code Online (Sandbox Code Playgroud)
给我 …
在数值应用程序中,我想知道计算完成后是否发生浮点异常.默认情况下,将以静默方式忽略浮点除法和无效操作.
我的尝试是启用我关心的FPE,通过设置标志来处理SIGFPE并再次禁用它们以允许继续执行:
#include <fenv.h>
#include <signal.h>
#include <stdio.h>
int caught = 0;
struct sigaction old_sa;
/* (2) */ fenv_t fenv_hold;
void sighandler()
{
caught = 1;
printf("Caught in handler, disabling\n");
/* (1) */ fedisableexcept(FE_ALL_EXCEPT);
/* (2) */ feholdexcept(&fenv_hold);
sigaction(SIGFPE, &old_sa, NULL);
}
int main(void)
{
struct sigaction sa;
volatile double a=1, b=0;
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_SIGINFO;
sa.sa_sigaction = sighandler;
sigaction(SIGFPE, &sa, &old_sa);
feenableexcept(FE_DIVBYZERO);
printf("Dividing by zero..\n");
a/=b;
printf("Continuing\n");
}
Run Code Online (Sandbox Code Playgroud)
我采取了两种方法,第一种标记(1),第二种标记(2).它们都没有按预期工作.
输出:
Dividing by zero..
Caught in …Run Code Online (Sandbox Code Playgroud) 要安装目录文件,我想获得Glade(UI设计器)的目录,如下所示:
$ pkg-config --variable=catalogdir gladeui-2.0
/usr/share/glade/catalogs
Run Code Online (Sandbox Code Playgroud)
但是在我的Makefile.am中的变量中。有(便携式)方法可以做到这一点吗?
我希望我的 UI 根据屏幕是否合成(从而支持某些效果)来更改设计。是否有可能
解决方案:
为了向不太熟悉 X11 API 的人详细说明 Andrey Sidorov 的正确答案,这是用于检测符合 EWMH 的合成器的代码:
int has_compositor(Display *dpy, int screen) {
char prop_name[20];
snprintf(prop_name, 20, "_NET_WM_CM_S%d", screen);
Atom prop_atom = XInternAtom(dpy, prop_name, False);
return XGetSelectionOwner(dpy, prop_atom) != None;
}
Run Code Online (Sandbox Code Playgroud) 我很惊讶地发现,显然std::forward不能与任意类型一起使用,尽管文档表明这一点.
#include <utility>
template<typename T>
void bar(T&&);
template<typename T>
void foo(T&& v) {
bar(std::forward(v));
}
int main() {
foo(main);
}
Run Code Online (Sandbox Code Playgroud)
产生
forward.cc: In instantiation of 'void foo(T&&) [with T = int (&)()]':
forward.cc:12:13: required from here
forward.cc:8:23: error: no matching function for call to 'forward(int (&)())'
bar(std::forward(v));
^
forward.cc:8:23: note: candidates are:
In file included from /usr/include/c++/4.8.2/bits/stl_pair.h:59:0,
from /usr/include/c++/4.8.2/utility:70,
from forward.cc:1:
/usr/include/c++/4.8.2/bits/move.h:76:5: note: template<class _Tp> constexpr _Tp&& std::forward(typename std::remove_reference<_From>::type&)
forward(typename std::remove_reference<_Tp>::type& __t) noexcept
^
/usr/include/c++/4.8.2/bits/move.h:76:5: note: template argument …Run Code Online (Sandbox Code Playgroud) c++ ×6
c++11 ×3
gcc ×3
g++ ×2
rust ×2
arrays ×1
assert ×1
autoconf ×1
automake ×1
autotools ×1
borrowing ×1
c ×1
cmake ×1
coding-style ×1
glade ×1
gtk ×1
gtk3 ×1
lifetime ×1
linux ×1
mutable ×1
overloading ×1
pkg-config ×1
pointers ×1
signals ×1
templates ×1
themes ×1
warnings ×1
x11 ×1
xlib ×1