小编Mik*_*eMB的帖子

将并发向量转换为 std::vector

我正在寻找将 aconcurrent_vector从 PPL 库转换为普通 std::vector 的推荐方法。

我有一个函数,它在 a 中返回其结果,std::vector但内部可能使用也可能不使用并行算法。目前我正在使用insert将元素从并发向量复制到法线向量:

#ifdef PARALLEL
    std::vector<Foo> Bar() {
        concurrency::concurrent_vector<Foo> cv;

        //Fill cv in a parallel algorithm

        std::vector<Foo> sv;
        sv.insert(sv.begin(), cv.begin(), cv.end());
        return sv;
    }
#else
    std::vector<Foo> Bar() {
        std::vector<Foo> sv;

        //Fill sv in a sequential algorithm

        return sv;
    }
#endif
Run Code Online (Sandbox Code Playgroud)

虽然插入操作的性能目前还不是一个真正的问题(与函数体相比),但它似乎没有必要,我想知道是否有更好的解决方案(顺便说一句:Foo是一个不能移动的简单 POD)。

理想情况下我想要有类似的东西

std::vector<Foo> Bar() {
    concurrency::concurrent_vector<Foo> cv;

    //Fill cv in a parallel algorithm

    return static_cast<std::vector<Foo>>(cv);
}
Run Code Online (Sandbox Code Playgroud)

或者至少

std::vector<Foo> Bar() {
    concurrency::concurrent_vector<Foo> cv;

    //Fill cv in …
Run Code Online (Sandbox Code Playgroud)

c++ concurrency c++11 ppl visual-studio-2013

6
推荐指数
1
解决办法
5743
查看次数

标准化2D/3D矢量/坐标类

问题现在
这个问题困扰着我,但我无法找到明确的答案:

  • 是否有人知道有关向STL引入标准2D和/或3D矢量(具有x,y和z成员的结构)的提议?
  • 如果没有,是否有一种现实的方法可以将这样的课程纳入标准的下一版本 - 缺少自己编写一份完整且完美的书面提案?
  • 并且,有什么好的理由(除了没有人有时间)为什么还没有这样做?

我绝对愿意做出贡献,但我相信我缺乏足够高质量的东西才能被接受(我不是专业程序员).

推理/背景
到现在为止,我已经看到了几十个库和框架(无论是图形,物理,数学,导航,传感器融合等......)都基本上都是实现了自己的版本

struct Vector2d {
    double x,y;
    //...
};
/* ...
 * operator overloads
 */
Run Code Online (Sandbox Code Playgroud)

和/或它的3D等价物 - 更不用说在我花时间做一个合适的,可重复使用的版本之前我自己实现的所有场合.
显然,这并不困难,我不担心次优的实现,但每次,我想组合两个库或重用来自不同项目的代码,我必须注意将一个版本转换为另一个版本(通过铸造或 - 如果可能 - 文本替换).

既然委员会正在努力扩展c ++ 17的标准库(特别是使用2D图形框架),我真的希望从一开始就将一个共同的2D向量融入所有接口,所以我可以编写例如:

drawLine(transformCoordinates(trackedObject1.estimatePos(),params), 
         transformCoordinates(trackedObject2.estimatePos(),params));
Run Code Online (Sandbox Code Playgroud)

而不是

MyOwnVec2D t1{trackedObject1.estimatePosX(), trackedObject1.estPosY()};
MyOwnVec2D t2{trackedObject2.estimatePosX(), trackedObject2.estPosY()};

t1 = transformCoordinates(t1,params);
t2 = transformCoordinates(t2,params);

drawLine(t1.x,t1.y,t2.x,t2.y);
Run Code Online (Sandbox Code Playgroud)

这个例子可能有点夸张,但我认为这表明了我的观点.

我知道std::valarray,它已经朝着正确的方向前进,因为它允许标准操作,如加法和乘法,但如果你只需要两个或三个坐标,它就会带来太多的重量.我认为具有固定大小且没有动态内存分配(例如基于std::array)的valarray 将是一个可接受的解决方案,特别是因为它将带有一个简单的迭代器实现,但我个人更喜欢具有x,y(和z)的类成员.

备注:如果这个话题已经讨论过了,我很抱歉(如果没有,我会感到惊讶),但每次我搜索2d向量时,我都会得到结果,std::vector<std::vector<T>>或者如何实现某个转换,但没有关于标准化的主题.

c++ standards stl

6
推荐指数
1
解决办法
1744
查看次数

从信号处理程序唤醒线程

我理解唯一的事情,ISO/C++ 11中允许的信号处理程序是读取或写入一个无锁的原子变量或者volatile sig_atomic_t(我相信,POSIX有点更宽松,允许调用一堆系统函数).

我想知道,如果有任何办法,唤醒正在等待条件变量的线程.就像这样:

#include <mutex>
#include <atomic>
#include <condition_variable>


std::mutex mux;
std::condition_variable cv;

std::atomic_bool doWait{ true };

void signalHandler(int){
    doWait = false;
    cv.notify_one();
}

int main() {
    //register signal handler
    //Do some stuff

    {//wait until signal arrived
        std::unique_lock<std::mutex> ul(mux);
        cv.wait(ul, []{return !doWait; });
    }

    //Do some more stuff
}
Run Code Online (Sandbox Code Playgroud)

其中至少有两个问题:

  1. 我相信,我不允许打电话notify_one()给信号处理程序(如果我错了,请告诉我)
  2. 信号可以在检查doWait和线程进入休眠之间到达,因此它永远不会被唤醒(显然,我无法锁定signalHander中的互斥锁以避免这种情况).

到目前为止,我能看到的唯一解决方案是在doWait变量上实现忙等待(可能在每次迭代中休眠几毫秒),这让我觉得非常低效.

请注意,即使我上面的程序只有一个线程,我用多线程标记了我的问题,因为它是关于线程控制原语.如果标准c ++中没有解决方案,我愿意接受使用Linux/POSIX特定功能的解决方案.

c++ linux multithreading signals signal-handling

6
推荐指数
1
解决办法
2178
查看次数

Visual Studio 自动为函数名称添加括号

VS2015(对于 C++)中是否有选项或(免费)扩展,以便当 Intellisense 自动完成函数名称(在调用站点)时,它还会添加左括号和右括号并将光标设置在它们之间?

c++ intellisense autocomplete visual-studio

6
推荐指数
1
解决办法
2196
查看次数

使用 clang-format 缩进 C++ lambda

有没有办法以 clang 格式缩进 c++11/14 lambda 体?此外,右大括号应与[]

所以我希望它看起来像这样

auto l = []( int max ) -> std::vector<int> {
            std::vector<int> v( max );
            std::iota( v.begin(), v.end(), 0 );
            return v;
         };
Run Code Online (Sandbox Code Playgroud)

代替

auto l = []( int max ) -> std::vector<int> {
    std::vector<int> v( max );
    std::iota( v.begin(), v.end(), 0 );
    return v;
};
Run Code Online (Sandbox Code Playgroud)

c++ lambda clang-format

6
推荐指数
0
解决办法
840
查看次数

从std :: string_view派生的对象的比较在MSVC中是不明确的

TL; DR: 我能想到的是下面的代码将编译任何C++ 17兼容标准的C++工具链(基于当前的C++ 17的提案)和MSVC未能这样做,是在执行中的错误?

#include <string_view>

struct Foo : std::string_view {};

int main() {
  Foo f1{};
  Foo f2{};
  return f1 == f2;
}
Run Code Online (Sandbox Code Playgroud)

说明:
我有一个派生自std::string_view并且没有实现自己的比较运算符的类,因为std::string_view语义正是我需要的,我也希望它可以与例如a相媲美std::string.

但是,如果我尝试比较该类的两个实例,MSVC 2017会抱怨具有类似转换的多个重载:

example.cpp
/opt/compiler-explorer/windows/19.10.25017/lib/native/include/xlocale(314): warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify /EHsc
8 : <source>(8): error C2666: 'std::operator ==': 3 overloads have similar conversions
/opt/compiler-explorer/windows/19.10.25017/lib/native/include/exception(336): note: could be 'bool std::operator ==(const std::exception_ptr &,const std::exception_ptr &) throw()' [found using argument-dependent lookup]
/opt/compiler-explorer/windows/19.10.25017/lib/native/include/exception(341): note: …
Run Code Online (Sandbox Code Playgroud)

c++ c++-standard-library visual-c++ c++17

6
推荐指数
1
解决办法
516
查看次数

创建两个可变的非类型模板参数包的笛卡尔积扩展

可以说,我有

  • 两个非类型模板参数列表(可能有不同的类型)
  • 一个模板foo,它将每个列表的一个值作为参数

如何创建foos 的可变参数包,使用两个列表元素的笛卡尔积进行参数化?

这就是我的意思:

template<int ...>
struct u_list {};

template<char ...>
struct c_list {};

template<int, char >
struct foo {};

template<class ...>
struct bar {};

using int_vals = u_list<1, 5, 7>;
using char_vals = c_list<-3, 3>;


using result_t = /* magic happens*/
using ref_t = bar<
    foo<1, -3>, foo<1, 3>,
    foo<5, -3>, foo<5, 3>,
    foo<7, -3>, foo<7, 3>
>;

static_assert(std::is_same<result_t, ref_t >::value, "");
Run Code Online (Sandbox Code Playgroud)

我正在寻找一个适用于c ++ 11的解决方案,并且不使用除c ++ 11标准库之外的任何库.我也有我的handroled版本的c ++ 14's index_sequence/ make_index_sequence并且可以提供非类型参数列表作为数组,如果这简化了代码. …

c++ cartesian-product template-meta-programming variadic-templates c++11

6
推荐指数
1
解决办法
699
查看次数

std :: strftime的返回值

我想我在某处读到如果我将nullptr传递给std :: strftime,该函数将返回所需的缓冲区大小.事实上,以下代码在我尝试过的众多Linux系统上运行得非常好(不是在使用VS编译时):

#include <iostream>
#include <ctime>
#include <string>

int main()
{
    std::time_t time{};
    std::tm const * ltime = std::localtime(&time);

    const char * formatString = "%Y-%b-%d";
    //allocate buffer of appropriate size
    auto requiredSize = 1 + std::strftime(nullptr, 50, formatString, ltime);
    std::cout << "Required buffer size:" << requiredSize << "\n";

    //Format time to string
    std::string buff(requiredSize, ' ');
    std::strftime(&buff[0], requiredSize, formatString, ltime);

    std::cout << buff << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

但是,我无法找到我的原始源或任何其他指定此行为的文档.所以我的问题是:

  • 在哪些系统/编译器/标准库实现(如果有)这是一个保证行为?
  • 我在哪里可以找到相应的文件?

编辑:我添加了C标签,因为我已经看到了相同的C代码相同的结果,至少使用gcc/g ++(或者更确切地说是glibc/libstdc ++)std::strftime可能只是c函数的别名strftime.

c c++ glibc

5
推荐指数
1
解决办法
501
查看次数

ABI-视觉工作室c库的兼容性

我的理解是(除了从VS2015切换到VS2017的明显例外),Microsoft使ABI在每个版本的Visual C++工具链之间进行了重大更改.因此,如果我想分发库的二进制版本,我必须为我想要支持的每个新版本的VS分发一个单独的版本.

现在我的问题是:

  • 纯c-library也是如此吗?
  • dll和静态库的答案有何不同?
  • MS是否有关于未来目标的官方政策?

(特别是考虑到crt重构和稳定性)

如果这是相关的,我会满足于特定于Win10的答案,但我也对所有Windows版本感兴趣,因为(包括)Win7.我感兴趣的VS Studio的版本是VS2013/15/17,并且 - 就任何预测而言 - 将来的版本.

c abi visual-studio universal-crt

5
推荐指数
1
解决办法
375
查看次数

列表初始化是否将原子初始化为零?

问题:

是否std::atomic<int> a{};初始化a(为零)?

背景:

通常,我希望T a{};要么给出编译时错误,要么确保它a已初始化并可供使用。要么是因为T是基本/类似 POD 的类型,并且关于聚合/零/值/列表初始化的语言规则导致所有内容都初始化为零(我不知道到底是什么),要么是因为调用默认构造函数“通常" 使对象进入可用状态。当然,需要(不仅仅是允许)双重初始化的类是存在的,但似乎相当罕见——特别是在标准库中。

然而,构造函数的文档 std::atomic

1) 默认构造函数很简单:除了静态和线程局部对象的零初始化之外,不进行任何初始化。std::atomic_init 可以用来完成初始化。

[...]

默认初始化的 std::atomic 不包含 T 对象,其唯一有效用途是 std::atomic_init 的销毁和初始化,请参阅LWG 2334

我读到这个

std::atomic<int> a{};
assert(a.load() == 0);
Run Code Online (Sandbox Code Playgroud)

不仅不能保证,而且实际上是未定义的行为。

如果是这样的话,那么恕我直言,这是使用原子的一个主要陷阱,特别是因为它似乎是在大多数平台上“按预期”工作的 UB 案例之一:https: //godbolt.org/g/二甲基乙二醇二乙醚

编辑:我也不太明白,为什么这“确保与 C 的兼容性”仅仅保证所有位都设置为零会有什么危害?

注意: 我知道我可以写std::atomic<int> a{0}

c++ initialization atomic

5
推荐指数
1
解决办法
1546
查看次数