我想知道是否可以在C++中的unordered_map容器中使用对象引用作为键.
#include <unordered_map>
class Object {
int value;
};
struct object_hash {
inline size_t operator()(const Object& o) const { return 0; }
};
std::unordered_map<Object&, int, object_hash> map;
Run Code Online (Sandbox Code Playgroud)
在尝试编译这个简单的代码片段时,我遇到了一些关于方法重新定义的错误:
使用clang和libc ++
/ usr/include/c ++/v1/unordered_map:352:12:错误:类成员无法重新声明
size_t operator()(const _Cp&__ x)const
使用gcc 4.6和libstdc ++
/usr/include/c++/4.6/bits/hashtable_policy.h:556:5:错误:'std :: __ detail :: _ Map_base <_Key,_Pair,std :: _ Select1st <_Pair>,true,_Hashtable> :: mapped_type&std :: __ detail :: _ Map_base <_Key,_Pair,std :: _ Select1st <_Pair>,true,_Hashtable> :: operator [with _Key = Object&,_ Pair = std :: pair,_Hashtable = std :: …
什么是检查的具体C++中的11个功能中存在的一个好方法标准库.
对于编译器功能,我只是检查(IMHO)主要编译器的编译器版本(目前VC++,gcc,clang,也许是英特尔)虽然这不是最好和最灵活的方法,但我不知道还有更好的东西,除了有非常好的宏的铿锵声__has_feature.
但是对于库特征来说更糟糕的是,这些特征并没有严格地与编译器耦合.目前我想使用相同的方法来检查VC++的编译器版本(假设它使用自己的库,它很容易).对于clang,我至少可以__has_include用于大规模的基于头的查询.除此之外我想__GLIBCXX__如果定义检查的值可能是一个好主意,但是我再次找不到任何特定libstdc ++版本引入哪些功能的信息,除了当前版本支持的功能.
这些方法应该保留给预处理器检查等,因为我想在没有任何复杂的配置过程的情况下在只有头的库中使用它而不使用任何第三方库(是的,boost是第三方).
那么在这些(非常狭窄的)条件下检查特定C++ 11库特征的可能性是什么呢?甚至可能在声明的特定功能或类型的规模上?
如果检查编译器或库版本仍然是最好的方法,我在哪里可以找到有关特定版本的libstdc ++支持的特定C++ 11特性的详细信息(也许还有其他重要的特性,libc ++)?
FWIW目前我对<cstdint>C++ 11的<cmath>功能感兴趣std::hash,但这可能会改变,对于一般方法可能并不重要.
我正在尝试使用clang编译一个C++程序,我在这里使用打包版本安装https://launchpad.net/~eudoxos/+archive/llvm-3.1.这是命令:
clang++ -std=c++11 -stdlib=libc++ -g -v -c main.cpp
Run Code Online (Sandbox Code Playgroud)
我得到了这个结果:
ignoring nonexistent directory "/usr/include/c++/v1"
ignoring nonexistent directory "/usr/bin/../lib/clang/3.1/include"
ignoring nonexistent directory ""
ignoring duplicate directory "/usr/include/x86_64-linux-gnu"
#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/usr/include/clang/3.1/include
/usr/include/x86_64-linux-gnu
/usr/include
main.cpp:1:10: fatal error: 'iostream' file not found
#include <iostream>
Run Code Online (Sandbox Code Playgroud)
如您所见,它不是在正确的包含目录/usr/include/c++/4.6中搜索.但我认为问题比这更深刻.即使我强制它在该目录中搜索,我得到这个:
In file included from main.cpp:1:
/usr/include/c++/4.6/iostream:38:10: fatal error: 'bits/c++config.h' file not found
#include <bits/c++config.h>
Run Code Online (Sandbox Code Playgroud)
该文件在该区域不存在.我想也许libc ++缺失了,但是在我尝试从源代码编译libc ++之前(我怀疑它会起作用)之前我找不到任何专用的libc ++ ubuntu包,我希望你们能帮帮忙.
非常感谢!
如果我启用c ++ 11和libc ++,我甚至无法使用clang编译一个简单的hello世界.例如以下代码
#include <iostream>
int main()
{
std::cout << "Hello, World!" << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我运行时从编译生成以下输出 clang++ -std=c++11 -stdlib=libc++ main.cpp
In file included from main.cpp:1:
In file included from /usr/bin/../lib/c++/v1/iostream:38:
In file included from /usr/bin/../lib/c++/v1/ios:216:
In file included from /usr/bin/../lib/c++/v1/__locale:15:
In file included from /usr/bin/../lib/c++/v1/string:434:
In file included from /usr/bin/../lib/c++/v1/algorithm:591:
/usr/bin/../lib/c++/v1/type_traits:165:12: error: unknown type name
'_LIBCPP_CONSTEXPR'
static _LIBCPP_CONSTEXPR const _Tp value = __v;
^
/usr/bin/../lib/c++/v1/type_traits:165:30: error: expected member name or ';'
after declaration specifiers
static _LIBCPP_CONSTEXPR const …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用简单的内存池分配器std::unordered_map.我使用这个相同的分配器似乎成功地使用了std::string和std::vector.我希望unordered_map(和vector)中包含的项目也使用这个分配器,所以我已经包装了我的分配器std::scoped_allocator_adaptor.
简化的定义集:
template <typename T>
using mm_alloc = std::scoped_allocator_adaptor<lake_alloc<T>>;
using mm_string = std::basic_string<char, std::char_traits<char>, mm_alloc<char>>;
using mm_vector = std::vector<mm_string, mm_alloc<mm_string>>;
using mm_map = std::unordered_map<mm_string, mm_vector, std::hash<mm_string>, std::equal_to<mm_string>, mm_alloc<std::pair<mm_string, mm_vector>>>;
Run Code Online (Sandbox Code Playgroud)
初始化如下:
lake pool;
mm_map map { mm_alloc<std::pair<mm_string, mm_vector>>{pool} };
Run Code Online (Sandbox Code Playgroud)
lake_alloc下面显示了迭代器代码的其余部分.我在Clang 3.3中得到的错误是它不能将它allocator_type(在这种情况下是字符串对的mm_alloc)转移到它自己的错误__pointer_allocator.这是用于哈希映射实现的内部类型.部分错误输出如下:
lib/c++/v1/__hash_table:848:53: error: no matching conversion for functional-style
cast from 'const allocator_type' (aka 'const std::__1::scoped_allocator_adaptor<krystal::krystal_alloc<std::__1::pair<std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::scoped_allocator_adaptor<krystal::krystal_alloc<char, krystal::lake> > >, std::__1::vector<std::__1::basic_string<char,
std::__1::char_traits<char>, std::__1::scoped_allocator_adaptor<krystal::krystal_alloc<char, krystal::lake> > >,
std::__1::scoped_allocator_adaptor<krystal::krystal_alloc<std::__1::basic_string<char, std::__1::char_traits<char>, …Run Code Online (Sandbox Code Playgroud) 编辑/更新/注意:让clang使用libstdc ++.到目前为止,我一直在为我工作.
===============================
在过去,我已经能够通过做某事来取得成功cmake,但刚才我在项目树buildit的lib目录中发现了一个脚本http://llvm.org/svn/llvm-project/libcxx/trunk.
这个buildit脚本似乎不会让使用libsupc++这是什么cmake我采取的办法之前使用.例如,本指南显示了一个cmake生成makefile的咒语libc++,它将能够处理编译和安装.
我的问题是这些生产LLVM的不同方法之间的区别是什么libc++?应该使用哪种方法?他们会表现得不一样吗?
该buildit脚本似乎没有提供任何安装帮助.有没有方向可以正确安装库?使用我之前使用cmake构建的libc ++,我必须始终添加-lc++到链接器标志(和路径-L),这在我的OS X makefile中是不必要的.
我试图在OSX 10.9 64位上静态链接libc ++
这是我做的:
1)通过修改libc ++源附带的脚本"buildit",构建一个带有fPIC的libc ++ 64.a.
2)使用fPIC构建我自己的所有源,并将我自己的include路径添加到新的libc ++源包含目录,同时使用-nostdinc ++作为编译标志.
3)链接"../build/libc++64.a"
我确信它会获取静态库,但它仍然会给我一个错误:
ld: illegal text-relocation to '__ZTVSt9bad_alloc' in /usr/lib/libc++.dylib from '__ZN3slm15ReadProblemFileERNS_5ModelERNS_3LogEPKwb' in bin/clang-darwin-4.2.1/release/address-model-64/threading-multi/read.o for architecture x86_64
Run Code Online (Sandbox Code Playgroud)
我不明白的是为什么以及它如何定位和使用 /usr/lib/libc++.dylib
更新:
当我在同一台机器上为32位执行相同的交叉构建时,构建成功,但我仍然依赖于libc ++.来自otool -L的dylib输出:
bin/clang-darwin-4.2.1/release/address-model-32/threading-multi/libsulum20.dynlib: libsulum20.dynlib (compatibility version 0.0.0, current version 0.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1197.1.1) /usr/lib/libc++.1.dylib (compatibility version 1.0.0, current version 120.0.0)
Run Code Online (Sandbox Code Playgroud) 随机(这就是我问这个问题的原因),我的应用程序在想要将数据显示到textView时崩溃了.
我在调试控制台中遇到的唯一错误消息是:
libc++abi.dylib: terminate_handler unexpectedly threw an exception
Run Code Online (Sandbox Code Playgroud)
我用谷歌搜索,但无法找到一个线索,找到这是如何正确以及如何发生这种情况.
我想建立一个最近的clang + llvm + libc ++.我目前正在使用一个系统(基于CentOS 6.6),我不能轻易获得clang的二进制包,但是我可以通过设置一些环境变量来建立一个足够用于构建clang(例如4.9)的GCC.
我想要我的铿锵声
-rpath $ORIGIN)我可以做到这一点,但它涉及将clang,llvm,libc ++,libc ++ abi(以及我可能忘记的事情)放在一棵树上,从一个构建目录构建clang,然后盲目地设置很多标志并再次从第二个构建目录.
是否有另一种适当的方式来引导libc ++?我相信一定有,因为llvm&clang的官方二进制文件就像我上面描述的那样是自给自足的.
这是非常基本的代码:
#include <memory>
class foo
{
public:
~foo() noexcept(false) { }
};
int main()
{
auto x = std::make_shared<foo>();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编译如下:
g++ -std=c++11 test.cpp <-- OK
clang++ -std=c++11 test.cpp <-- OK
clang++ -std=c++11 -stdlib=libc++ test.cpp <-- FAIL
Run Code Online (Sandbox Code Playgroud)
使用libc ++编译时,它会失败:
/usr/bin/../include/c++/v1/memory:3793:7: error: exception specification of overriding function is more lax than base version
class __shared_ptr_emplace
^
/usr/bin/../include/c++/v1/memory:4423:26: note: in instantiation of template class 'std::__1::__shared_ptr_emplace<foo,
std::__1::allocator<foo> >' requested here
::new(__hold2.get()) _CntrlBlk(__a2, _VSTD::forward<_Args>(__args)...);
^
/usr/bin/../include/c++/v1/memory:4787:29: note: in instantiation of function template …Run Code Online (Sandbox Code Playgroud)