在 libc++ 中, 的特化std::array<T,0>有一个成员 ( const)char数组,该数组根据T(源) 进行对齐和调整大小。我想知道这个实现的原因是什么,因为这个成员(__elems_)似乎没有在任何地方使用。为了进行比较,libstdc++使用空成员,而Microsoft STL如果不可默认构造则使用空成员T(否则,它会创建单元素数组)。
差异的现场演示:https ://godbolt.org/z/1o167na6z
在OS X 10.8上使用libc ++时,以下代码无法使用XCode 4.5的clang ++进行编译:
#include <map>
#include <string>
class Foo {
public:
explicit Foo(int val_) : val(val_) {}
int val;
};
struct FooComparator {
bool operator()(const Foo& left, const Foo& right) {
return left.val < right.val;
}
};
int main(int argc, char* argv[]) {
std::map<Foo, std::string, FooComparator> m;
Foo f(4);
m[f] = std::string("four");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
错误:
broken.cpp:11:8:注意:候选函数不可行:'this'参数的类型为'const FooComparator',但是方法没有标记为const bool operator()(const Foo&left,const Foo&right){
如果我关闭libc ++并使用libstdc ++构建,那么一切都很好.显然,我可以通过制作FooComparator :: operator()const来解决这个问题,但是我想知道这是否是libc ++过于严格的问题,还是标准(C++ 03和C++ 11)确实要求比较器的operator()是const(在这种情况下,它与libstdc ++一起工作的事实是一个幸福的事故).
编辑:这不是问如何做std::make_heapO(n)方式,而是这个特定的实现是否确实是O(n)
在O(n)时间内构建堆的教科书方法是从下到上依次构建堆.但是std::make_heap在我的Mac机器上用libc ++实现的是
template <class _RandomAccessIterator, class _Compare>
inline _LIBCPP_INLINE_VISIBILITY
void
make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
{
#ifdef _LIBCPP_DEBUG
typedef typename add_lvalue_reference<__debug_less<_Compare> >::type _Comp_ref;
__debug_less<_Compare> __c(__comp);
__make_heap<_Comp_ref>(__first, __last, __c);
#else // _LIBCPP_DEBUG
typedef typename add_lvalue_reference<_Compare>::type _Comp_ref;
__make_heap<_Comp_ref>(__first, __last, __comp);
#endif // _LIBCPP_DEBUG
}
Run Code Online (Sandbox Code Playgroud)
在哪里__make_heap定义为
template <class _Compare, class _RandomAccessIterator>
void
__make_heap(_RandomAccessIterator __first, _RandomAccessIterator __last, _Compare __comp)
{
typedef typename iterator_traits<_RandomAccessIterator>::difference_type difference_type;
difference_type __n = __last - __first;
if (__n > 1)
{
__last …Run Code Online (Sandbox Code Playgroud) 我想使用Clang和LibTooling来创建一些C++源代码分析和转换工具.我按照本教程构建了Clang和LibTooling ,并且我已经能够使用我构建的Clang二进制文件运行并创建一些分析工具并编译C++程序.但是,如果我包含标准库中的标头(在源文件或我的工具中),则在编译或运行源文件/工具时会遇到问题.例如,如果我对以下C++源文件运行clang-check:
#include <iostream>
int main() {
std::cout << "Hello";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我收到"致命错误:找不到'iostream'文件".(注意:我可以编译C++程序,例如那些使用用户定义类的程序,而不是使用标准库的C++程序.)为了解决这个问题,我构建了libc ++(遵循本指南,在llvm/project中构建它)我构建LLVM和Clang的目录,但是我仍然无法使用Clang和使用libc ++的工具.现在,如果我尝试使用以下方法编译测试文件:
export CPLUS_INCLUDE_PATH="~/clang-llvm/llvm/projects/libcxx/include"
export LD_LIBRARY_PATH="~/clang-llvm/llvm/projects/libcxx/lib"
~/clang-llvm/llvm/build/bin/clang++ ~/Documents/main.cpp
Run Code Online (Sandbox Code Playgroud)
然后我得到"致命错误:'找不到'unistd.h'文件".所以我的问题是:我如何正确地指出Clang和我的工具使用libc ++?
我正在运行OS X Yosemite 10.10并使用Clang 3.6.0.
我看到这两个项目非常相关,但它们之间有什么区别?官方网页并没有说太多.
我知道ABI(应用程序二进制接口)用于在不同平台之间提供低级二进制接口.那么libc ++ abi用于为不同的平台提供不同的实现,以及libc ++的通用接口吗?
更好的是给出一些具体的例子,例如libc ++ abi中包含的内容以及libc ++中的内容.
谢谢.
std::chrono::years (since C++20) duration</*signed integer type of at least 17 bits*/, std::ratio<31556952>>
使用libc++,似乎std::chrono::yearsis的下划线存储是short有符号的16 位。
std::chrono::years( 30797 ) // yields 32767/01/01
std::chrono::years( 30797 ) + 365d // yields -32768/01/01 apparently UB
Run Code Online (Sandbox Code Playgroud)
cppreference或其他任何内容是否有错别字?
例子:
#include <fmt/format.h>
#include <chrono>
template <>
struct fmt::formatter<std::chrono::year_month_day> {
char presentation = 'F';
constexpr auto parse(format_parse_context& ctx) {
auto it = ctx.begin(), end = ctx.end();
if (it != end && *it == 'F') presentation = *it++;
# …Run Code Online (Sandbox Code Playgroud) 根据cppreference,std::string_view::operator==是constexpr.我很难找到适合当前库实现的情况.
这是我试过的:
#include <string_view>
constexpr char x0[] = "alpha";
constexpr char y0[] = "alpha";
constexpr auto x = std::string_view(x0, 5);
constexpr auto y = std::string_view(y0, 5);
constexpr auto a = std::string_view("alpha", 5);
constexpr auto b = std::string_view("alpha", 5);
int main()
{
// a, b, x, y are all constexpr, operator== is constexpr
// therefore I expected this to compile:
static_assert(x == y);
static_assert(a == b);
}
Run Code Online (Sandbox Code Playgroud)
使用gcc-trunk,这不会编译,因为在libstdc ++中,operator ==根本不是constexpr.
使用clang-trunk时,这也会失败,因为operator ==()被声明为constexpr,但是使用的char_traits :: compare()不是constexpr.
这些错误是否在标准库中?或者我的期望是错的?
如果我的期望是错误的,那么我如何构建一个可以进行constexpr比较的string_view?
我认为这是在LLVM/Clang下编译时名称空间'std'中名为'unique_ptr'的No类型问题的一部分.据Marshall Clow说,我可以-stdlib=libc++通过_LIBCPP_VERSION以下方式检测:
如果您正在编写跨平台代码,有时您需要知道您正在使用的标准库.从理论上讲,它们都应该提供相同的功能,但这只是理论.有时你只需要知道.检查libc ++的最佳方法是查找预处理器符号_LIBCPP_VERSION.如果已定义,那么您正在使用libc ++.
Run Code Online (Sandbox Code Playgroud)#ifdef _LIBCPP_VERSION // libc++ specific code here #else // generic code here #endif
不幸的是,在从LLVM项目下载后,我使用Apple的Clang(3.4-SVN)和Clang(3.6)来解决这个问题.我猜这个测试只在Xcode下有效.
如何-stdlib=libc++在预处理器中可靠地检测?
以下是测试用例:
$ cat test-clapple.cxx
// Need to test {C++03,C++11} x {libc++, no libc++}
// c++ -c test-clapple.cxx
// - OK
// c++ -stdlib=libc++ -c test-clapple.cxx
// - OK
// c++ -std=c++11 -c test-clapple.cxx
// - FAILS, no type named 'unique_ptr' in namespace 'std'
// c++ -std=c++11 -stdlib=libc++ -c test-clapple.cxx
// …Run Code Online (Sandbox Code Playgroud) 基本上,我们有这个代码片段:
#include <cstdint>
#include <variant>
enum class Enum1 : std::uint8_t { A, B };
enum class Enum2 : std::uint8_t { C, D };
using Var = std::variant< Enum1, Enum2 >;
using Var2 = std::variant< char >;
template< std::size_t s >
struct print_size;
void func() {
print_size< sizeof( Var ) >{};
print_size< sizeof( Var2 ) >{};
}
Run Code Online (Sandbox Code Playgroud)
如果我们使用GCC的libstdc ++(使用clang或GCC)编译它,我们会得到预期的编译错误:
error: implicit instantiation of undefined template 'print_size<2>'
Run Code Online (Sandbox Code Playgroud)
此外,与MSVC类似(如预期):
error C2027: use of undefined type 'print_size<2>'
Run Code Online (Sandbox Code Playgroud)
但是,当使用clang与libc ++时,我收到此错误: …
我希望匹配所有以给定单词开头的行,比如iheap.如果我没有弄错,正则表达式(在ECMAScript语法中)"^iheap.*"应该可以解决问题.但是,当我使用libc ++的正则表达式库在C++ 11中测试它时,只匹配第一行.所以"^..."似乎只匹配输入的开头而不是开头的行.
这是一个例子:
#include <string>
#include <regex>
#include <iostream>
using namespace std;
int main() {
regex rx("^iheap.*");
string s = "iheap says hello.\niheap says hello again.\n";
cout << s << regex_replace(s, rx, "IHEAP");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
输出:
iheap says hello.
iheap says hello again.
IHEAP
iheap says hello again.
Run Code Online (Sandbox Code Playgroud)
这是libc ++的错误还是我做错了什么?谢谢!
注意:我使用的是Mac OS X Mountain Lion和Apple LLVM Compiler 4.0(基本上是clang 3.1 SVN的快照).
libc++ ×10
c++ ×9
clang ×4
c++17 ×2
llvm ×2
c++-chrono ×1
c++11 ×1
c++20 ×1
gcc ×1
libtooling ×1
macos ×1
regex ×1
std-variant ×1
stdarray ×1
stl ×1