我很惊讶地发现is_swappable<T>并且is_nothrow_swappable<T>不属于新的C++ 11 type_traits元函数.它们对于传播noexcept模板和确定是否可以为模板实现非抛出交换非常有用.
的libc ++推出其自己的内部版本:看__is_swappable和__is_nothrow_swappable在其版本type_traits的,它使大量的内部使用它们,但不会让他们提供给外部.
我最终将我自己的这些版本拼凑起来用于个人项目,这似乎有效,但我确定它会以某种方式破坏.
我很好奇这两个缺席,因为它们看起来非常重要.在C++ 11标准化过程中是否考虑过此功能,还是仅仅是一个未包含在内的疏忽?如果考虑到了什么,导致它没有被纳入最终标准(缺乏时间,实施问题等)?是否有缺陷报告或进化论文讨论这个问题?有没有计划在C++ 1Y中加入这些特性?某处有一个公认的"正确"版本吗?
我发现gcc(4.9.2)和clang(3.5.0)之间的行为有所不同,令我感到惊讶.
当我尝试unsigned int从一个std::istringstream带有负值的初始值(在示例中为"-15")中提供一个时,我得到了
fail()clang ++ 出错(带位)signed(-15)用gcc ++ 初始化我准备了以下示例程序.
#include <sstream>
#include <iostream>
int main ()
{
std::istringstream iss("-15");
unsigned int ui;
iss >> ui;
std::cout << "ui[" << ui << "] signed(ui)[" << signed(ui)
<< "] flags[" << iss.fail() << iss.good() << iss.bad()
<< iss.eof() << "]\n";
return 0;
}
Run Code Online (Sandbox Code Playgroud)
使用clang ++,我获得以下输出
ui[0] signed(ui)[0] flags[1001]
Run Code Online (Sandbox Code Playgroud)
使用g ++,我获得以下输出
ui[4294967281] signed(ui)[-15] flags[0001]
Run Code Online (Sandbox Code Playgroud)
我有两个问题.
首先是显而易见的:谁是对的?clang ++,g ++还是一个未定义的行为?
第二个是:我如何强制gcc ++的行为类似于clang ++,从一个以减号开头的字符串中提取无符号值时会出错?
谢谢,抱歉我的英语不好.
编辑2016.04.03
我意识到这不是g ++和clang ++之间的区别,而是libstd …
在Linux系统上,我试图通过调用在运行时调用程序system().系统调用以不等于零的返回码退出.
调用WEXITSTATUS错误代码给出"127".
根据系统的手册页,此代码表示/bin/sh无法调用:
如果/bin/sh无法执行,退出状态将是执行命令的退出状态exit(127).
我查了一下:/bin/sh是一个链接bash.bash在那儿.我可以从shell执行它.
现在,我怎么才能找出/bin/sh无法调用的原因?任何内核历史或什么?
编辑:
在这个过程非常有用的提示(见下文)之后strace -f -p <PID>.这是我在system通话中得到的:
Process 16080 detached
[pid 11779] <... select resumed> ) = ? ERESTARTNOHAND (To be restarted)
[pid 11774] <... wait4 resumed> [{WIFEXITED(s) && WEXITSTATUS(s) == 127}], 0, NULL) = 16080
[pid 11779] --- SIGCHLD (Child exited) @ 0 (0) ---
[pid 11779] rt_sigaction(SIGCHLD, {0x2ae0ff898ae2, [CHLD], SA_RESTORER|SA_RESTART, 0x32dd2302d0}, <unfinished …Run Code Online (Sandbox Code Playgroud) 我正在研究std::vectorlibc ++ 中的实现,我注意到它内部保留了三个指针(一个指向开头,一个结束,一个指向已分配内存的末尾),而不是我本能地做的,即,一个指针开始和两个size和capacity成员.
这是来自libc ++的代码<vector>(忽略压缩对,我知道它意味着什么).
pointer __begin_;
pointer __end_;
__compressed_pair<pointer, allocator_type> __end_cap_;
Run Code Online (Sandbox Code Playgroud)
我注意到其他标准库也做同样的事情(例如Visual C++).我没有看到为什么这个解决方案应该比另一个解决方案更快的任何特殊原因,但我可能是错的.
那么"三指针"解决方案是否优于"指针+尺寸"解决方案?
我想知道是否unordered_map使用类型擦除实现,因为unordered_map<Key, A*>并且unordered_map<Key, B*>可以使用完全相同的代码(除了强制转换,这是机器代码中的无操作).也就是说,两者的实现可以基于unordered_map<Key, void*>保存代码大小.
更新:此技术通常被称为精简模板成语(感谢下面的评论者指出这一点).
更新2:我对Howard Hinnant的观点特别感兴趣.我希望他读到这个.
所以我写了这个小测试:
#include <iostream>
#if BOOST
# include <boost/unordered_map.hpp>
using boost::unordered_map;
#else
# include <unordered_map>
using std::unordered_map;
#endif
struct A { A(int x) : x(x) {} int x; };
struct B { B(int x) : x(x) {} int x; };
int main()
{
#if SMALL
unordered_map<std::string, void*> ma, mb;
#else
unordered_map<std::string, A*> ma;
unordered_map<std::string, B*> mb;
#endif
ma["foo"] = new …Run Code Online (Sandbox Code Playgroud) 我想在CentOS 7上使用带有clang/clang ++的C++ 11或C++ 14.如何构建这个构建环境?
我想知道在Ubuntu上安装二进制libc ++的正确/简单方法是什么,在我的案例中Trusty又名14.04?
在LLVM网站上有apt软件包http://apt.llvm.org/,我用这些软件包来安装3.9.但是这些包似乎不包含libc ++.我安装了libc ++ - dev包,但这似乎是一个非常古老的版本.还有可以下载的二进制文件http://llvm.org/releases/download.html#3.9.0.这些似乎包含libc ++,但我不确定我是否可以将这些内容复制到像/ usr/include/c ++/v1这样的地方,实际上我并不确定我需要复制哪些内容.我知道我可以从备用位置使用libc ++,如我在此处记录的http://libcxx.llvm.org/docs/UsingLibcxx.html.但是,我不能修改我工作的大型代码库的构建系统来执行此操作.
因此,apt包不包含libc ++的任何原因,并且任何指向安装二进制文件的指针都会感激不尽.
我正在尝试通过阅读C++ 14标准以及libc ++和libstdc ++的源代码来更深入地理解C++.type_traits两者之间的各种项目的实施情况各不相同,特别是is_move_assignable,我试图弄清楚哪些项目"更正确".
的libc ++:
template <class _Tp> struct is_move_assignable
: public is_assignable<typename add_lvalue_reference<_Tp>::type,
const typename add_rvalue_reference<_Tp>::type> {};
Run Code Online (Sandbox Code Playgroud)
的libstdc ++:
template<typename _Tp, bool = __is_referenceable<_Tp>::value>
struct __is_move_assignable_impl;
template<typename _Tp>
struct __is_move_assignable_impl<_Tp, false>
: public false_type { };
template<typename _Tp>
struct __is_move_assignable_impl<_Tp, true>
: public is_assignable<_Tp&, _Tp&&>
{ };
template<typename _Tp>
struct is_move_assignable
: public __is_move_assignable_impl<_Tp>
{ };
Run Code Online (Sandbox Code Playgroud)
标准规定:
对于可引用类型
T,结果与is_assignable<T&, T&&>::value否则相同false.
我注意到的第一件事是libc ++适用const于第二个模板参数,这似乎不正确,因为移动赋值运算符采用非const rvalue.libstdc ++也使用__is_referenceable,遵循标准的措辞,但libc ++没有.是通过规定的libc …
考虑以下测试程序:
#include <iostream>
#include <string>
#include <vector>
int main()
{
std::cout << sizeof(std::string("hi")) << " ";
std::string a[10];
std::cout << sizeof(a) << " ";
std::vector<std::string> v(10);
std::cout << sizeof(v) + sizeof(std::string) * v.capacity() << "\n";
}
Run Code Online (Sandbox Code Playgroud)
输出libstdc++和libc++分别是:
8 80 104
24 240 264
Run Code Online (Sandbox Code Playgroud)
如您所见,libc++对于一个简单的程序,需要3倍的内存.实现有何不同会导致这种内存差异?我需要关注,我该如何解决它?