下面的代码不能用clang 3.1编译,使用libc ++(不知道版本,Xcode附带的当前版本).它适用于其他标准库.我的代码中是否有错误,或者这是libc ++中的错误?
#include <map>
#include <string>
using namespace std;
struct A {
A(const map<int, A>& m) {}
};
struct B {
map<string, A> m;
};
Run Code Online (Sandbox Code Playgroud)
我看到的错误是<utility>:
/usr/lib/c++/v1/utility:241:64: No member named 'value' in 'std::__1::is_nothrow_copy_constructible<A>'
Run Code Online (Sandbox Code Playgroud)
我试图进一步隔离它,但这是我发现的最小例子.有趣的是,当我更换string由int第二映射它的工作原理(也当我更换int由stringINT第一图):
map<string, A> m; // Does not work
map<int, A> m; // Works
Run Code Online (Sandbox Code Playgroud) 如果我启用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) 这是非常基本的代码:
#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) 我在我的Ubuntu 13.04机器上安装了clang 3.2,并编译和构建了libc ++,一切都已就绪.但是,当我尝试链接我的(非常简单的)代码时,链接器报告对std :: cout等的引用是未定义的.
如果有人能告诉我我能做些什么来解决这个问题,我会非常感激 - 我已经尝试了所有我能想到的东西.
命令和输出在这里:
$ clang++ -v -stdlib=libc++ -lpthread -ldl sqlite3/sqlite3.o src/world.o -o bin/world
Ubuntu clang version 3.2-1~exp9ubuntu1 (tags/RELEASE_32/final) (based on LLVM 3.2)
Target: x86_64-pc-linux-gnu
Thread model: posix
"/usr/bin/ld" -z relro --hash-style=gnu --build-id --eh-frame-hdr -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o bin/world /usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crt1.o /usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crti.o /usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/crtbegin.o -L/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7 -L/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu -L/lib/x86_64-linux-gnu -L/lib/../lib64 -L/usr/lib/x86_64-linux-gnu -L/usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../.. -L/lib -L/usr/lib -lpthread -ldl sqlite3/sqlite3.o src/world.o -lc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/crtend.o /usr/bin/../lib/gcc/x86_64-linux-gnu/4.7/../../../x86_64-linux-gnu/crtn.o
src/world.o: In function `main':
/home/douglivesey/work/home/cpp/clang/biots/src/world.cpp:17: undefined reference to `std::cout'
/home/douglivesey/work/home/cpp/clang/biots/src/world.cpp:17: …Run Code Online (Sandbox Code Playgroud) 在http://llvm.org/svn/llvm-project/libcxx/trunk/test/re/re.alg/re.alg.match/ecma.pass.cpp中,存在以下测试:
std::cmatch m;
const char s[] = "tournament";
assert(!std::regex_match(s, m, std::regex("tour|to|tournament")));
assert(m.size() == 0);
Run Code Online (Sandbox Code Playgroud)
为什么这场比赛会失败?
在VC++ 2012和boost上,匹配成功.
在Chrome和Firefox的Javascript上,"tournament".match(/^(?:tour|to|tournament)$/)成功.
仅在libc ++上,匹配失败.
随着我最近升级到Mac OS X 10.9,默认的标准C++库从libstdc ++更改为libc ++.从那时起,我观察到下面的代码示例中记录的字符串流运算符>>(double)的意外行为.
总之,当double值后跟一个字母时,libc ++似乎在从stringstreams中提取double值时遇到问题.
我已经检查过标准(2003)但是如果在这种情况下提取应该起作用,我找不到任何具体的信息.
所以,如果这是一个libc ++或libstdc ++中的错误,我将不胜感激.
#include <sstream>
#include <iostream>
using namespace std;
void extract_double(const string & s)
{
stringstream ss;
double d;
ss << s;
ss >> d;
if(!ss.fail())
cout << "'" << ss.str() << "' converted to " << d << endl;
else
cout << "'" << ss.str() << "' failed to convert to double" << endl;
}
int main()
{
extract_double("-4.9");
extract_double("-4.9 X");
extract_double("-4.9_");
extract_double("-4.9d");
extract_double("-4.9X");
}
Run Code Online (Sandbox Code Playgroud)
用c++ --stdlib=libc++ streamtest.cxx …
#if __cplusplus >= 201103L
template <class _Key, class _Tp>
union __value_type
{
typedef _Key key_type;
typedef _Tp mapped_type;
typedef pair<const key_type, mapped_type> value_type;
typedef pair<key_type, mapped_type> __nc_value_type;
value_type __cc;
__nc_value_type __nc;
template <class ..._Args>
_LIBCPP_INLINE_VISIBILITY
__value_type(_Args&& ...__args)
: __cc(std::forward<_Args>(__args)...) {}
_LIBCPP_INLINE_VISIBILITY
__value_type(const __value_type& __v)
: __cc(__v.__cc) {}
_LIBCPP_INLINE_VISIBILITY
__value_type(__value_type& __v)
: __cc(__v.__cc) {}
_LIBCPP_INLINE_VISIBILITY
__value_type(__value_type&& __v)
: __nc(std::move(__v.__nc)) {}
_LIBCPP_INLINE_VISIBILITY
__value_type& operator=(const __value_type& __v)
{__nc = __v.__cc; return *this;}
_LIBCPP_INLINE_VISIBILITY
__value_type& operator=(__value_type&& __v)
{__nc = std::move(__v.__nc); return *this;}
_LIBCPP_INLINE_VISIBILITY
~__value_type() …Run Code Online (Sandbox Code Playgroud) 我想明白为什么内联函数的libc ++可见性宏使用__forceinline或__attribute__((__always_inline__))作为与内联函数关联的属性的一部分.
有关背景,请参阅
如果这些内联函数将被标记为__visibility__("hidden")无论如何,为什么还需要强制编译器内联它们?
我已经考虑了一下,我有一些假设,但似乎没有一个对我完全满意:
hidden属性不足够吗?同样,在构建库时是否只需要强制内联函数?消费者不应该在意.visibility("hidden")吗?我问这个是因为我正在构建一个C++库,我希望有一天能够标准化ABI,我正在使用libc ++作为指导.到目前为止,它运作良好,但这个问题引起了一些人头疼.
特别是,我们有报道称用户抱怨MSVC拒绝遵守该__forceinline属性,从而导致警告.我们提出的解决方案是__forceinline在构建库时将模拟扩展到INLINE_VISIBILITY仅包括(或GCC等效),假设上面的第一个解释.
但是,由于我们并不完全相信我们理解强制内联函数背后的原因,__forceinline或者__attribute__((__always_inline__))首先,我们对采用这种解决方案有点犹豫不决.
任何人都可以提供一个明确的答案,为什么libc ++需要强制内联其内联函数,即使它们已被装饰为具有隐藏的可见性?
最近,我想知道如何nullptr工作.在http://www.stroustrup.com/N1488-nullptr.pdf中,我找到了代码.(对不起,我没有10个声誉,所以我不能在这里发布图片,你可以点击上面的链接,代码在第3页.)
代码很酷.我搜索的关键字nullptr在Woboq再次,我发现LLVM的源代码是与上述不同,我将它们复制以下.
struct _LIBCPP_TEMPLATE_VIS nullptr_t
{
void* __lx;
struct __nat {int __for_bool_;};
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t() : __lx(0) {}
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR nullptr_t(int __nat::*) : __lx(0) {}
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR operator int __nat::*() const {return 0;}
template <class _Tp>
_LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR
operator _Tp* () const {return 0;}
template <class _Tp, class _Up>
_LIBCPP_ALWAYS_INLINE
operator _Tp _Up::* () const {return 0;}
friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator==(nullptr_t, nullptr_t) {return true;}
friend _LIBCPP_ALWAYS_INLINE _LIBCPP_CONSTEXPR bool operator!=(nullptr_t, nullptr_t) {return …Run Code Online (Sandbox Code Playgroud)