小编Die*_*ühl的帖子

为什么不能移动std :: ostream?

显然,无法复制流.应该可以移动流.根据27.9.1.11 [ofstream.cons]段4有可能移动的构造std::ofstream(同为真std::ifstream,std::fstreamstd::*stringstream变体).例如:

#include <iostream>
#include <fstream>
#include <string>

std::ofstream makeStream(std::string const& name) {
    return std::ofstream(name);
}

int main()
{
    std::ofstream out{ makeStream("example.log") };
}
Run Code Online (Sandbox Code Playgroud)

试图运动std::ostream,例如,有一个工厂函数创建一个std::ofstream,一个std::ostringstream,或者根据参数不起作用通过了URN一些其他的流.std::ostream(std::basic_ostream实际上,类模板)protected根据27.7.3.1 [ostream] 有一个移动构造函数.

为什么不能自己std::ostream移动?

c++ iostream c++11

56
推荐指数
1
解决办法
4099
查看次数

如何从std :: istream中安全地读取一行?

我想安全地读一行std::istream.流可以是任何东西,例如,Web服务器上的连接或处理由未知来源提交的文件的东西.有许多答案开始做这个代码的道德等价物:

void read(std::istream& in) {
    std::string line;
    if (std::getline(in, line)) {
        // process the line
    }
}
Run Code Online (Sandbox Code Playgroud)

鉴于可能的可疑来源in,使用上述代码会导致漏洞:恶意代理可能会使用巨大的线路对此代码发起拒绝服务攻击.因此,我想将线路长度限制在一个相当高的值,比如4百万char秒.虽然可能会遇到一些大行,但为每个文件分配缓冲区并使用是不可行的std::istream::getline().

如何限制线路的最大尺寸,理想情况下不会过于严重地扭曲代码并且不预先分配大块内存?

c++

52
推荐指数
4
解决办法
2万
查看次数

如何使用C++概念("concepts lite")支持构建gcc?

C++标准委员会正在研究概念扩展的TS(技术规范):"Programming Languages - C++ Extensions for Concepts".N4377是本文档的最新版本.为了包含在C++标准中,要求实现功能,理想情况是可公开访问的系统.

我知道概念-gcc,但上面的概念提议(通俗地称为Concepts Lite)是不同的.我听说有一个概念的分支,我已经尝试了origin/asutton/c++-conceptsGCCgit镜,但没有编制.如何构建和使用上述[草案] TS中指定的gcc支持概念版本?

c++ g++ generic-programming c++-concepts c++17

39
推荐指数
2
解决办法
7364
查看次数

如何使用<random>替换rand()?

C++ 11引入了<random>带有随机数引擎和随机分布声明的头文件.那很好 - 取代那些用途的时间rand()往往会以各种方式出现问题.但是,如何更换它似乎远非显而易见

srand(n);
// ...
int r = rand();
Run Code Online (Sandbox Code Playgroud)

基于声明,似乎可以构建如下的统一分布:

std::default_random_engine engine;
engine.seed(n);
std::uniform_int_distribution<> distribution;
auto rand = [&](){ return distribution(engine); }
Run Code Online (Sandbox Code Playgroud)

这种方法似乎相当复杂,并且肯定是我不记得的东西,不像使用srand()rand().我知道N4531,但即使这样看起来仍然非常复杂.

是否有一个相当简单的方式来代替srand()rand()

c++ random c++11

30
推荐指数
3
解决办法
5682
查看次数

使用STL并行算法的用户有哪些限制?

在杰克逊维尔会议上,有效采用Parallelism TS规范的提议P0024r2被接受到C++ 17(草案)中.该提议为许多算法添加了重载,这些算法采用执行策略参数来指示应该考虑哪种并行性.在(20.19.2 [执行])中已经定义了三个执行策略:<execution>

  • std::execution::sequenced_policy(20.19.4 [execpol.seq])带有一个constexpr对象std::execution::seq(20.19.7 [parallel.execpol.objects])来表示顺序执行,类似于在没有执行策略的情况下调用算法.
  • std::execution::parallel_policy(20.19.5 [execpol.par])带有一个constexpr对象std::execution::par(20.19.7 [parallel.execpol.objects]),表示可能使用多个线程执行算法.
  • std::execution::parallel_unsequenced_policy(20.19.6 [execpol.vec])带有一个constexpr对象std::execution::par_unseq(20.19.7 [parallel.execpol.objects]),表示可能使用向量执行和/或多个线程执行算法.

STL算法通常将用户定义的对象(迭代器,函数对象)作为参数.用户定义的对象有哪些限制,使它们可以使用标准执行策略与并行算法一起使用?

例如,当使用如下例中的算法时,对FwdItand 的含义是Predicate什么?

template <typename FwdIt, typename Predicate>
FwdIt call_remove_if(FwdIt begin, FwdIt end, Predicate predicate) {
    return std::remove_if(std::execution::par, begin, end, predicate);
}
Run Code Online (Sandbox Code Playgroud)

c++ stl c++17

30
推荐指数
1
解决办法
1383
查看次数

通用函数的重载是否可以为其他重载打开?

我想实现一些通用算法,我有很多想法,如何根据算法使用的实体的某些特征来实现专门的算法.但是,似乎我没有提出所有特殊特性,我想实现通用版本,以便它们可以与另一个专用版本一起使用.

例如,考虑distance(begin, end)(是的,我知道它在标准库中;但是,它很好很简单,可以用来演示我的问题).一般版本可能看起来像这样(我正在使用std::ptrdiff_t而不是std::iterator_traits<It>::difference_type另一种简化):

template <typename It>
auto distance(It it, It end) -> std::ptrdiff_t {
    std::ptrdiff_t size{};
    while (it != end) {
        ++it;
        ++size;
    }
    return size;
}
Run Code Online (Sandbox Code Playgroud)

当然,如果迭代器类型是随机访问迭代器,那么使用两个迭代器之间的差异来实现算法要好得多.天真地加入

template <typename It>
auto distance(It begin, It end)
     -> typename std::enable_if<is_random_access_v<It>, std::ptrdiff_t>::type {
    return end - begin;
}
Run Code Online (Sandbox Code Playgroud)

并不是很有效:两个实现对于随机访问迭代器都是同样好的匹配,即编译器认为它们是不明确的.处理这种情况的简单方法是将一般实现更改为仅适用于非随机访问迭代器.也就是说,SFINAE的选择使得它们相互排斥,同时也覆盖整个空间.

不幸的是,这组实现仍然是关闭的:至少在没有改变签名的情况下,我不能添加另一个实现,以防我对利用特殊属性的泛型实现有另一个想法.例如,如果我想为分段范围添加特殊处理(想法:当基础序列按原样由段组成时,例如,std::deque<...>或者std::istreambuf_iterator<cT>单独处理段的情况),则有必要将一般实现更改为仅适用当序列不是随机访问且它不是分段序列时.当然,如果我控制可以完成的实现.用户将无法扩展通用实现集.

我知道可以为特殊迭代器类型重载函数.但是,这将要求每次添加具有特殊功能的迭代器时,都需要实现相应的功能.目标是允许添加通用实现,这些实现是在它们被使用的实体暴露额外设施的情况下改进的.它类似于不同的迭代器类别,尽管属性与迭代器类别正交.

因此,我的问题是:

  • 可以实现通用算法,以便可以在不改变现有实现的情况下添加新的改进构思,如果是这样,如何实现?
  • 可选的后续行动(我主要对上面的问题感兴趣,但这也可能很有趣):如果不可能,这个能力是否会添加概念?

c++ templates generic-programming c++11 c++14

24
推荐指数
2
解决办法
406
查看次数

可以从三元运算符抛出异常吗?

有时候只需要一个语句(返回时就必须这样)是方便的,甚至是必要的constexpr.如果需要检查条件并且只允许一个语句,则条件运算符是唯一的选项.如果出现错误,最好从条件运算符中抛出异常,例如:

template <typename It>
typename std::iterator_traits<It>::reference
access(It it, It end) {
    return it == end? throw std::runtime_error("no element"): *it;
}
Run Code Online (Sandbox Code Playgroud)

但是,当用作例如(实例)时,上述函数不会编译:

std::vector<int> v;
access(v.begin(), v.end());
Run Code Online (Sandbox Code Playgroud)

编译器抱怨尝试将非const引用绑定到临时.不过,编译器并没有抱怨throw-expression本身.所以问题是:可以从条件运算符抛出异常,如果是这样,上面的代码出了什么问题?

c++ constexpr c++11

23
推荐指数
3
解决办法
1456
查看次数

为什么新的C++标准使用"ISO/IEC 14882:2015"?

根据ISO网站,新标准被命名为"ISO/IEC 14882:2015 "而不是"ISO/IEC 14882:2014 ".为什么会如此,这会改变吗?例如,有许多标记为C++ 14的东西.

如果你有兴趣在技术含量,而不是标准的文件,它可以从github上ISO C++库N4140.

c++ iso c++14

22
推荐指数
1
解决办法
2240
查看次数

调用函数对象时如何保证参数评估的顺序?

关于如何在使用std :: make_tuple时避免构造函数的未定义执行顺序的问题的答案导致了一个讨论,在此期间我了解到构造函数可以保证参数评估的顺序:使用braced-init-list命令保证从左到右:

T{ a, b, c }
Run Code Online (Sandbox Code Playgroud)

表达式a,bc,按给定的顺序进行评估.即使类型T只定义了普通的构造函数,也是如此.

显然,并非所有被调用的都是构造函数,有时候在调用函数时保证求值顺序会很好,但是没有像brace-argument-list这样的东西来调用函数,并且定义了对它们的参数的评估顺序.问题变成:构造函数的保证是否可以用于构建函数调用工具(" function_apply()"),并具有用于评估参数的排序保证?要求调用函数对象是可以接受的.

c++ c++11

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

为什么`std :: pair <int,movable>`需要一个[deleted]`const&`copy constructor?

我正忙着测试各种通用算法的实现,而我正在使用对提供的函数支持最少的类型.当使用std::pair<T, movable>某种类型T(例如int)和movable类似定义的类型时,我遇到了这种奇怪的设置:

struct movable
{
    movable() {}
    movable(movable&&) = default;
    // movable(movable const&) = delete;
    movable(movable&) = delete;
};
Run Code Online (Sandbox Code Playgroud)

这个想法有一种可移动但不可复制的类型.这很好用,例如,使用这样的表达式:

movable m1 = movable();
movable m2 = std::move(m1);
Run Code Online (Sandbox Code Playgroud)

但是,当尝试使用此类型作为其成员std::pair<...>时失败!为了使代码得到编译,有必要添加deleted(!)复制构造函数来获取movable const&(或只有该版本).采用非const引用的复制构造函数是不够的:

#include <utility>
auto f() -> std::pair<int, movable> {
    return std::pair<int, movable>(int(), movable());
}
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?是std::pair<...>通过强制要求overspecified std::pair(std::pair const&)= default编?

问题似乎std::pair取决于复制构造函数的规范(在20.3.2 [pairs.pair]概要中):

 namespace std {
     template <class T1, class T2> …
Run Code Online (Sandbox Code Playgroud)

c++ stl c++-standard-library c++11

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