我正在使用pimpl-idiom std::unique_ptr:
class window {
window(const rectangle& rect);
private:
class window_impl; // defined elsewhere
std::unique_ptr<window_impl> impl_; // won't compile
};
Run Code Online (Sandbox Code Playgroud)
但是,我在第304行的第304行收到有关使用不完整类型的编译错误<memory>:
'
sizeof'到不完整类型'uixx::window::window_impl的应用无效' '
据我所知,std::unique_ptr应该可以使用不完整的类型.这是libc ++中的错误还是我在这里做错了什么?
这个答案给出了短字符串优化(SSO)的一个很好的高级概述.但是,我想更详细地了解它在实践中是如何工作的,特别是在libc ++实现中:
为了符合SSO资格,字符串有多短?这取决于目标架构吗?
在访问字符串数据时,实现如何区分短字符串和长字符串?它m_size <= 16是一个简单的,还是一个标志,是其他成员变量的一部分?(我想这m_size或其中的一部分也可能用于存储字符串数据).
我专门针对libc ++问了这个问题,因为我知道它使用SSO,甚至在libc ++主页上也提到过.
以下是查看来源后的一些观察结果:
libc ++可以使用两个稍微不同的字符串类内存布局进行编译,这由_LIBCPP_ALTERNATE_STRING_LAYOUT标志控制.这两种布局还区分了little-endian和big-endian机器,这使我们总共有4种不同的变体.我将在下面的内容中假设"正常"布局和小端.
假设进一步size_type是4个字节并且value_type是1个字节,这就是字符串的前4个字节在内存中的样子:
// short string: (s)ize and 3 bytes of char (d)ata
sssssss0;dddddddd;dddddddd;dddddddd
^- is_long = 0
// long string: (c)apacity
ccccccc1;cccccccc;cccccccc;cccccccc
^- is_long = 1
Run Code Online (Sandbox Code Playgroud)
由于短字符串的大小在高7位,因此在访问它时需要移位:
size_type __get_short_size() const {
return __r_.first().__s.__size_ >> 1;
}
Run Code Online (Sandbox Code Playgroud)
类似地,长字符串容量的getter和setter用于__long_mask解决这个问题is_long.
我仍在寻找我的第一个问题的答案,即__min_cap短字符串的容量对不同的架构有什么价值?
其他标准库实现
这个答案很好地概述了std::string其他标准库实现中的内存布局.
第23.3.7节vector<bool>[vector.bool]第1段规定:
template <class Allocator> class vector<bool, Allocator> {
public:
// types:
typedef bool const_reference;
...
Run Code Online (Sandbox Code Playgroud)
但是,当使用libc ++时,此程序无法编译:
#include <vector>
#include <type_traits>
int
main()
{
static_assert(std::is_same<std::vector<bool>::const_reference, bool>{}, "?");
}
Run Code Online (Sandbox Code Playgroud)
此外,我注意到C++标准在本规范中一直与C++ 98一致.我还注意到自从第一次引入libc ++以来,libc ++一直没有遵循这个规范.
这种不合格的动机是什么?
我正在使用c/c ++为osx和linux开发命令行界面可执行文件.该项目将链接到opencv.我应该使用libc ++还是libstdc ++?
我在Mac OS X(10.8.2)下使用C++工作,最近我想出了使用C++ 11功能的需求,这些功能可以通过使用libc ++ stdlib的clang ++编译器获得.但是,我还需要使用一些针对libstdc ++编译和链接的遗留库(来自MacPorts).
在这样做时,我得到了链接错误,因为遗留库的标题使用,例如std::string,需要解决std::__1::basic_string(即,libc ++实现std::string)而不是std::basic_string实现.
有没有办法在开发中混合两个库(例如,通过使用一些预处理器标志?)
编译boost :: program_options的示例代码:http://svn.boost.org/svn/boost/trunk/libs/program_options/example/first.cpp
...在MacOS Lion(10.7.2)上,使用随MacPorts安装的boost-1.48.0:
$ clang++ -v
Apple clang version 3.0 (tags/Apple/clang-211.12) (based on LLVM 3.0svn)
Target: x86_64-apple-darwin11.2.0
Thread model: posix
$ clang++ -std=c++0x --stdlib=libc++ -lc++ -I/opt/local/include -L/opt/local/lib -lboost_program_options first.cpp -o first
Undefined symbols for architecture x86_64:
"boost::program_options::options_description::options_description(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, unsigned int, unsigned int)", referenced from:
_main in cc-6QQcwm.o
"boost::program_options::operator<<(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, boost::program_options::options_description const&)", referenced from:
_main in cc-6QQcwm.o
"boost::program_options::abstract_variables_map::operator[](std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const", referenced from:
boost::program_options::variables_map::operator[](std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) const in …Run Code Online (Sandbox Code Playgroud) 这个问题的答案为什么不能用c ++ 0x模式中的libc ++来扼制这个boost :: program_options例子?陈述"你需要使用clang ++ -stdlib = libc ++重建boost."
我正在使用带有clang v3.0的MacOS Lion.如何使用clang构建Boost v1.48.0并将其与libc ++链接?
更新:我已经创建了一个user-config.jam文件,其中包含以下内容:
using clang-darwin
Run Code Online (Sandbox Code Playgroud)
...将使用clang而不是gcc构建Boost.如何链接libc ++而不是libstdc ++?
我与尝试shared_ptr,并make_shared从C++ 11和编程的小玩具的例子来看看调用时什么是实际发生的事情make_shared.作为基础设施,我使用llvm/clang 3.0以及XCode4中的llvm std c ++库.
class Object
{
public:
Object(const string& str)
{
cout << "Constructor " << str << endl;
}
Object()
{
cout << "Default constructor" << endl;
}
~Object()
{
cout << "Destructor" << endl;
}
Object(const Object& rhs)
{
cout << "Copy constructor..." << endl;
}
};
void make_shared_example()
{
cout << "Create smart_ptr using make_shared..." << endl;
auto ptr_res1 = make_shared<Object>("make_shared");
cout << "Create smart_ptr using make_shared: done." …Run Code Online (Sandbox Code Playgroud) 一般来说,默认构造函数应该是创建空容器的最快方法。这就是为什么我惊讶地发现它比初始化为空字符串文字更糟糕:
#include <string>
std::string make_default() {
return {};
}
std::string make_empty() {
return "";
}
Run Code Online (Sandbox Code Playgroud)
编译为:(clang 16,libc++)
make_default():
mov rax, rdi
xorps xmm0, xmm0
movups xmmword ptr [rdi], xmm0
mov qword ptr [rdi + 16], 0
ret
make_empty():
mov rax, rdi
mov word ptr [rdi], 0
ret
Run Code Online (Sandbox Code Playgroud)
请参阅编译器资源管理器中的实时示例。
请注意,返回{}总共将 24 个字节归零,但返回""仅将 2 个字节归零。怎么会return "";好很多呢?
我正在尝试在Xcode 8中使用LLDB来调试非常基本的STL.我曾经能够打印这样的矢量:
p myvector[0]
Run Code Online (Sandbox Code Playgroud)
看第一个矢量索引中的内容.现在,当我这样做时,我收到此错误:
error: Couldn't lookup symbols:
__ZNSt3__16vectorI9my_classNS_9allocatorIS1_EEEixEm
Run Code Online (Sandbox Code Playgroud)
相反,我必须输入:
p myvector.__begin_[0]
Run Code Online (Sandbox Code Playgroud)
为了获得任何输出.
我尝试从LLDB svn存储库导入libcxx.py和unordered_multi.py脚本,但这似乎没有改变任何东西.
有没有人能够通过libc ++从LLDB获得任何有用的输出?
libc++ ×10
c++ ×9
clang ×5
boost ×2
c++11 ×2
libstdc++ ×2
linux ×1
lldb ×1
macos ×1
make-shared ×1
opencv ×1
optimization ×1
shared-ptr ×1
std-bitset ×1
stdstring ×1
stl ×1
string ×1
unique-ptr ×1
vector ×1
xcode ×1