小编gig*_*tes的帖子

如何检测类型是否可以流式传输到std :: ostream?

我正在尝试编写一个类型特征来检测一个类型是否重载了适合用于输出流的operator <<().

我错过了一些东西,因为我总是认为一个简单的空类没有操作符.

这里的代码:

template<typename S, typename T>
class is_streamable
{
    template<typename SS, typename TT>
    static auto test(SS&& s, TT&& t)
    -> decltype(std::forward<SS>(s) << std::forward<TT>(t));

    struct dummy_t {};
    static dummy_t test(...);

    using return_type = decltype(test(std::declval<S>(), std::declval<T>()));

public:
    static const bool value = !std::is_same<return_type, dummy_t>::value;
};

class C {};

int main() {
    std::cout << is_streamable<std::stringstream, C>::value << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

1
Run Code Online (Sandbox Code Playgroud)

这是在ideone:https://ideone.com/ikSBoT

我究竟做错了什么?

c++ templates iostream template-meta-programming c++11

31
推荐指数
2
解决办法
3023
查看次数

在自定义容器类中使用分配器

我正在开发一个类似容器的类,我想使用标准的分配器基础结构,就像标准容器一样.在网上我找到了很多关于如何std::allocator单独使用该类的材料,或者如何为标准容器定义自定义分配器,但是关于如何一般地使用标准符合分配器的材料是非常罕见的,特别是在C++ 11的上下文,从谁编写自定义分配器的角度来看,事情似乎要容易得多,但从容器的角度来看更复杂.

所以我的问题是如何以最通用的方式正确使用标准的符合标准的分配器,具体来说:

  • 首先,我应该何时以这种方式设计自定义容器?使用默认分配器而不是普通的新/删除是否有明显的性能开销(包括缺少优化机会)?
  • 我是否必须显式调用包含对象的析构函数?
  • 如何区分有状态和无状态分配器?
  • 如何处理有状态分配器?
    • 当(如果有的话)两个实例可以互换时(何时可以用一个实例销毁分配给另一个实例的内存)?
    • 复制容器时必须复制它们?
    • 移动容器时可以/必须移动它们吗?
    • 在容器的移动构造函数和移动赋值运算符中,何时可以将指针移动到已分配的内存,何时必须分配不同的内存并移动元素?
  • 在这种情况下是否存在关于异常安全的问题?

我对C++ 11世界的答案特别感兴趣(它在C++ 14中有什么改变吗?)

c++ memory-management c++11

18
推荐指数
1
解决办法
1858
查看次数

为什么libc ++ std :: vector在内部保留三个指针而不是一个指针和两个大小?

我正在研究std::vectorlibc ++ 中的实现,我注意到它内部保留了三个指针(一个指向开头,一个结束,一个指向已分配内存的末尾),而不是我本能地做的,即,一个指针开始和两个sizecapacity成员.

这是来自libc ++的代码<vector>(忽略压缩对,我知道它意味着什么).

pointer                                    __begin_;
pointer                                    __end_;
__compressed_pair<pointer, allocator_type> __end_cap_;
Run Code Online (Sandbox Code Playgroud)

我注意到其他标准库也做同样的事情(例如Visual C++).我没有看到为什么这个解决方案应该比另一个解决方案更快的任何特殊原因,但我可能是错的.

那么"三指针"解决方案是否优于"指针+尺寸"解决方案?

c++ stl vector libc++

18
推荐指数
1
解决办法
1894
查看次数

基于深度优先顺序而不是宽度优先,我可以为完整的树提供类似堆的连续布局吗?

堆是一个经典的数据结构,它将完整的二进制(或通用版本的d-ary)树放入一个连续的数组中,以广度优先的遍历顺序存储元素.以这种方式,来自树的相同级别的所有元素一个接一个地连续存储.

我正在实现一个数据结构,在引擎盖下,它是一个完全平衡的固定度d树,我想以连续的形式存储树以释放节点指针的空间.所以我想把节点放在堆中使用的广度优先顺序中,但后来我担心从根到叶子的典型搜索的缓存性能,因为在每个级别l,我跳过了很多元素.

有没有办法获得基于深度优先顺序的d-ary完整树的紧凑连续表示?

这样,在搜索叶子期间触摸的节点似乎更容易被发现彼此更接近.那么问题是如何检索节点的父节点和子节点的索引,但我也想知道在这个设置中树上的哪些操作通常是有效的.

我正在用C++实现这个东西,万一它很重要.

c++ heap tree data-structures

17
推荐指数
1
解决办法
626
查看次数

在空的初始化列表上调用std :: min(并明确指定类型)未定义的行为?

std::min()使用空的初始化列表调用通常不会编译(所有问题都可以用相同的方式表示std::max()).这段代码:

#include <iostream>
#include <algorithm>

int main() {
   std::cout << std::min({}) << "\n";
   return 0;
}
Run Code Online (Sandbox Code Playgroud)

使用clang会出现此错误:

test.cpp:6:17: error: no matching function for call to 'min'
   std::cout << std::min({}) << "\n";
                ^~~~~~~~
algorithm:2599:1: note: 
      candidate template ignored: couldn't infer template argument '_Tp'
min(initializer_list<_Tp> __t)
Run Code Online (Sandbox Code Playgroud)

我可以看出为什么不允许这种情况,因为在这种情况下难以就回归的合理价值达成一致.

但是,从技术上讲,代码不能编译,因为无法推导出模板参数.如果我强制参数代码编译但我崩溃了:

#include <iostream>
#include <algorithm>

int main() {

  std::cout << std::min<int>({}) << "\n";

  return 0;
}

$ clang++ -std=c++11 test.cpp -o test
$ ./test 
Segmentation fault: 11
Run Code Online (Sandbox Code Playgroud)

似乎崩溃是因为std::min()实现了崩溃std::min_element(),并且空的初始化列表导致无效 …

c++ undefined-behavior stl-algorithm c++11 c++14

15
推荐指数
1
解决办法
952
查看次数

如何包含名称中包含“&gt;”的头文件?

我承认,这是一个非常人为的问题,但这是事实。

假设您有一个>名称中包含字符的文件。这在大多数Unix系统afaik上都是可能的:

$ touch 'weird>name'
$ ls -l
-rw-r--r--  1 user  user   0 28 Mag 11:05 weird>name
Run Code Online (Sandbox Code Playgroud)

现在,假设此文件包含C / C ++代码,并且您希望将其作为标头包括在内:

#include <weird>name>

int main() {
  return weird_function();
}
Run Code Online (Sandbox Code Playgroud)

lang给我以下错误:

test.cpp:1:10: fatal error: 'weird' file not found
#include <weird>name>
Run Code Online (Sandbox Code Playgroud)

当然,由于预处理程序将指令解析到第一个指令>并查找weird文件。但是,我想知道是否存在某种转义机制来允许我包含正确的文件。

因此,在C和/或C ++中,是否可以包含>名称中包含字符的头文件?

编辑:许多建议我为什么不使用#include "weird>name"。我承认在编写问题时我的脑海里忽略了引号语法,但是它仍然有效,因为这两种语法可能会要求编译器在不同的路径中搜索(至少在理论上是这样)。那么,是否有任何转义机制让我包括weird>name使用#include <>语法?

c c++ language-lawyer c-preprocessor

15
推荐指数
2
解决办法
1288
查看次数

从宏参数中删除最后一个尾随逗号

我需要从宏参数列表中删除最后一个尾随逗号(因为它们最终将扩展为不承认尾随逗号的模板参数)。

所以我需要一个remove_trailing_comma()名为 like 的宏remove_trailing_comma(arg1, arg2, arg3, )扩展为arg1, arg2, arg3.

我尝试过不同的可变参数组合,__VA_OPT__但似乎无法做到。

例如:

#define discard_trailing_comma(arg, ...) \
    arg __VA_OPT__(,) discard_trailing_comma(__VA_ARGS__)

discard_trailing_comma(1, 2, 3, )
Run Code Online (Sandbox Code Playgroud)

不起作用(使用 g++ 10),因为扩展为1 , discard_trailing_comma(2, 3,),我不知道为什么(宏不是递归扩展的吗?)

这在 C++20 中可能吗?

c++ c-preprocessor c++20

12
推荐指数
2
解决办法
945
查看次数

如何检测我的代码是否使用-fno-exceptions进行编译?

我正在编写一个C++库,我想让我的API抛出无效参数的异常,但是在编译代码时依赖于assert -fno-exceptions.

如果允许我使用异常处理,有没有办法在编译时检测?请注意,我正在编写一个只有头的库,所以我没有configure阶段,我无法访问构建系统,只需在命令行上定义一个宏(我不想增加负担给用户).

由于标准没有"-fno-exceptions"的任何概念,当然解决方案可能依赖于编译器.在这种情况下,我对使用g ++和clang ++的解决方案感兴趣,其他编译器对于这个项目并不重要.

非常感谢你

c++ g++ clang++

11
推荐指数
1
解决办法
1102
查看次数

基于用户定义的概念专门化命名空间 std 中的类型

在很多地方(例如这里)都写到,只有当专门化“取决于用户定义的类型”namespace std时才允许类型的专门化。标准中的此定义是否明确排除基于用户定义概念的特殊类型?std

例如,这是允许的吗?

namespace std {
  template<MyConcept T>
  struct hash<T> {
    size_t hash(T const& v) const { ... }
  };
}
Run Code Online (Sandbox Code Playgroud)

这将极大地简化我的代码中的许多专业化,其中我有很多不同但相似的类,它们遵循相同的概念,可以以相同的方式进行哈希处理。

c++ c++20

9
推荐指数
1
解决办法
102
查看次数

伪造子进程的日期/时间

在Unix系统上,是否可以伪造子进程的已知日期和时间?

即,想象一下:

$ date 
Fri Jun 28 10:50:35 CEST 2019

$ with_date 10/05/2019 date
Fri May 10 10:50:36 CEST 2019
Run Code Online (Sandbox Code Playgroud)

如何执行with_date命令?

典型的用例是测试与日期/时间相关的软件,模拟各种情况。

unix posix

7
推荐指数
1
解决办法
50
查看次数