std::function提供了一个rvalue引用的构造函数.按标准移动的函数对象会发生什么?它是否为空,以便再次调用它没有效果?
首先,请考虑以下情况.
以下是一个程序:
// test.cpp
extern "C" void printf(const char*, ...);
int main() {
printf("Hello");
}
Run Code Online (Sandbox Code Playgroud)
下面是一个图书馆:
// ext.cpp (the external library)
#include <iostream>
extern "C" void printf(const char* p, ...);
void printf(const char* p, ...) {
std::cout << p << " World!\n";
}
Run Code Online (Sandbox Code Playgroud)
现在我可以用两种不同的方式编译上面的程序和库.
第一种方法是在不链接外部库的情况下编译程序:
$ g++ test.cpp -o test
$ ldd test
linux-gate.so.1 => (0xb76e8000)
libc.so.6 => /lib/i386-linux-gnu/libc.so.6 (0xb7518000)
/lib/ld-linux.so.2 (0xb76e9000)
Run Code Online (Sandbox Code Playgroud)
如果我运行上面的程序,它将打印:
$ ./test
Hello
Run Code Online (Sandbox Code Playgroud)
第二种方法是使用指向外部库的链接编译程序:
$ g++ -shared -fPIC ext.cpp -o libext.so
$ g++ test.cpp -L./ -lext -o …Run Code Online (Sandbox Code Playgroud) 我是否需要一个extern "C" {}块来在C++程序中包含标准C头.只考虑在C++中没有对应项的标准C头.
例如:
extern "C" {
#include <fcntl.h>
#include <unistd.h>
}
Run Code Online (Sandbox Code Playgroud) boost :: log看起来非常强大.它为琐碎的日志记录提供了一个BOOST_LOG_TRIVIAL宏.但是如何更改默认格式?它默认打印时间戳,我不想要它.你有什么主意吗?似乎唯一的方法是从头部定义一个新的接收器并将其添加到核心,然后你可以在后端调用set_format()以防万一.但这不再是"微不足道的"了.
我试图使用自定义分配器std::vector<char>,但我注意到std::vector不需要/使用我的分配器中的任何成员函数.这怎么可能?
#include <vector>
struct A : private std::allocator<char> {
typedef std::allocator<char> alloc;
using alloc::value_type;
using alloc::pointer;
using alloc::const_pointer;
using alloc::difference_type;
using alloc::size_type;
using alloc::rebind;
// member functions have been removed, since the program compiles without them
};
int main() {
std::vector<char, A> v;
v.resize(4000);
for (auto& c : v)
if (c)
return 1; // never happens in my environment
return 0; // all elements initialized to 0. How is this possible?
}
Run Code Online (Sandbox Code Playgroud)
我正在使用在线C++ 11编译器(LiveWorkSpace)尝试上述程序,提供g ++ 4.7.2,4.8和4.6.3. …
为什么人们更愿意调用std :: ref而不是根本不调用它?
template<class F, class...Ts> F for_each_arg(F f, Ts&&...a) {
return (void)initializer_list<int>{(ref(f)((Ts&&)a), 0)...}, f;
// why not return (void)initializer_list<int>{(f((Ts&&)a), 0)...}, f;
}
Run Code Online (Sandbox Code Playgroud) 我正在使用GCC 4.8编译以下代码:
#include <memory>
template<typename T, typename ...Args>
std::unique_ptr<T> make_unique(Args&& ...args) {
return std::unique_ptr<T>(new T{std::forward<Args>(args)...});
}
struct S {
template<class... Args>
static std::unique_ptr<S> create(Args&&... args) {
return make_unique<S>(std::forward<Args>(args)...);
}
private: // if I remove this line, then the compilation is OK
S(int) {}
S() = default;
};
int main() {
auto s1 = S::create(); // OK
auto s2 = S::create(0); // Compilation error
}
Run Code Online (Sandbox Code Playgroud)
任何人都可以从编译器解释这个错误的原因吗?
main.cpp:实例化'std :: unique_ptr make_unique(Args && ...)[用T = S; Args = {int}]':
main.cpp:11:58:需要'static std :: unique_ptr …
考虑以下功能:
Widget f(Widget w) {
return w;
}
Run Code Online (Sandbox Code Playgroud)
假设Widget根据C++标准实现复制和移动构造函数,w必须在return语句中将其视为rvalue对象,以防编译器不认为复制省略是更好的选择.
另一方面,请考虑以下版本:
Widget f(Widget&& w) {
return w;
}
Run Code Online (Sandbox Code Playgroud)
至于对面的第一个版本,根据Item 25的Effective Modern C++,笔者似乎暗示回来w肯定会调用拷贝构造函数.换句话说,他建议返回std::move(w),以使编译器使用(可能更快)移动构造函数.
你能解释为什么第二版f()采取Widget&&的说法是不等同于第一个版本采取了Widget按值相对于构造被称为return语句,也考虑到在两者的功能体的表达w是指lvalue?
演示行为的完整示例:
#include <iostream>
struct Widget
{
Widget() { std::cout << "constructed" << std::endl; }
~Widget() { std::cout << "destructed" << std::endl; }
Widget(const Widget&) { std::cout << "copy-constructed" << std::endl; }
Widget(Widget&&) { std::cout …Run Code Online (Sandbox Code Playgroud) 我试图mmap()在预先标识的fd上替换原始系统调用LD_PRELOAD,以便调用它的进程可以读取由另一个进程先前创建的共享内存对象boost::interprocess.一切顺利,除非我最终尝试读取mmap的内存.在这种情况下,第一个进程以分段错误中止.原因是什么?我不需要对共享内存对象的写权限.
这是预加载库中的代码:
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) {
static void* (*o_mmap) ( void *, size_t, int, int, int, off_t ) =
o_mmap = (void*(*)( void *, size_t, int, int, int, off_t )) dlsym(RTLD_NEXT, "mmap");
if (!o_mmap)
std::cout << "mmap() preload failed\n";
if (fd != my_fd)
return (*o_mmap)( start, length, prot, flags, fd, offset );
interprocess::shared_memory_object shm (interprocess::open_only, "obj", interprocess::read_only);
interprocess::mapped_region region(shm, interprocess::read_only, 0, length, start);
std::cout …Run Code Online (Sandbox Code Playgroud) 是否允许符合C++ 11的编译器优化/转换此代码:
bool x = true; // *not* an atomic type, but suppose bool can be read/written atomically
/*...*/
{
while (x); // spins until another thread changes the value of x
}
Run Code Online (Sandbox Code Playgroud)
等同于无限循环的任何东西:
{
while (true); // infinite loop
}
Run Code Online (Sandbox Code Playgroud)
从单线程程序的角度来看,上述转换肯定是有效的,但这不是一般情况.
此外,在C++ 11之前是否允许优化?