在我最近评论的一段代码中,编译好了g++-4.6
,我遇到了一个奇怪的尝试来创建一个std::shared_ptr
来自std::unique_ptr
:
std::unique_ptr<Foo> foo...
std::make_shared<Foo>(std::move(foo));
Run Code Online (Sandbox Code Playgroud)
这对我来说似乎很奇怪.这应该是std::shared_ptr<Foo>(std::move(foo));
afaik,虽然我对动作并不完全熟悉(而且我知道std::move
只是演员,没有任何动静).
检查此SSC上的不同编译器(NUC*)E
#include <memory>
int main()
{
std::unique_ptr<int> foo(new int);
std::make_shared<int>(std::move(foo));
}
Run Code Online (Sandbox Code Playgroud)
编译结果:
所以问题是:哪个编译器在标准方面是正确的?标准是否要求这是一个无效的声明,一个有效的声明,或者这是不确定的?
加成
我们已经同意这些编译器中的一些,例如clang ++和g ++ - 4.6.4,允许转换,而不应该.但是对于g ++ - 4.7.3(会产生内部编译器错误std::make_shared<Foo>(std::move(foo));
),请正确拒绝int bar(std::move(foo));
由于这种巨大的行为差异,我将问题保持不变,尽管其中一部分将与减少相关int bar(std::move(foo));
.
*)NUC:不是普遍可编辑的
根据这个网站,使用MPI::COMM_WORLD.Send(...)
是线程安全的.但是在我的应用程序中,我经常(并非总是)遇到死锁或出现分段错误.MPI::COMM_WORLD
使用a 封闭每个方法调用mutex.lock()
并mutex.unlock()
始终如一地删除死锁以及段错误.
这是我创建线程的方式:
const auto communicator = std::make_shared<Communicator>();
std::vector<std::future<size_t>> handles;
for ( size_t i = 0; i < n; ++i )
{
handles.push_back(std::async(std::launch::async, foo, communicator));
}
for ( size_t i = 0; i < n; ++i )
{
handles[i].get();
}
Run Code Online (Sandbox Code Playgroud)
Communicator
是一个有std::mutex
成员的类,专门调用诸如MPI::COMM_WORLD.Send()
和之类的方法MPI::COMM_WORLD.Recv()
.我没有使用任何其他方法发送/接收MPI.foo
采取一个const std::shared_ptr<Commmunicator> &
论点.
我的问题:MPI承诺的线程安全性与创建的线程不兼容std::async
吗?
我有:
Windows 7/32bit上的-cygwin 1.7.25
-g ++ --version - > g ++(GCC)4.8.2
-libstdc ++.a - > gcc-g ++ - 4.8.2-1
试图制作一个c ++ Hello World:
#include <string>
int main()
{
std::string s = "123";
int i = std::stoi(s);
}
Run Code Online (Sandbox Code Playgroud)
编译给出:
$ g++ -std=c++11 main.cpp
main.cpp: In function ‘int main()’:
main.cpp:6:10: error: ‘stoi’ is not a member of ‘std’
int i = std::stoi(s);
Run Code Online (Sandbox Code Playgroud)
我搜索了几个小时,但我仍然找不到解决方案.这是什么问题?
我有通过cout和cerr写入控制台的OpenMP线程.这当然不安全,因为输出可以交错.我可以做点什么
#pragma omp critical(cerr)
{
cerr << "my variable: " << variable << endl;
}
Run Code Online (Sandbox Code Playgroud)
如果可以用线程安全版本替换cerr会更好,类似于valgrind DRD手册中解释的方法(http://valgrind.org/docs/manual/drd-manual.html#drd-manual.effective- use)涉及从std :: ostreambuf派生一个类.理想情况下,最后我会用自己的线程cerr替换cerr,例如:
tcerr << "my variable: " << variable << endl;
Run Code Online (Sandbox Code Playgroud)
一旦遇到"endl",这样的类就可以打印到控制台.我不介意来自不同线程的行是否是交错的,但每行应仅来自一个线程.
我真的不明白C++中的所有这些流是如何工作的,它太复杂了.有没有人这样的课程或者可以告诉我如何为此目的创建这样的课程?
考虑以下代码
#include <chrono>
#include <iostream>
#include <thread>
int main()
{
using std::chrono::system_clock;
using std::chrono::milliseconds;
using std::chrono::nanoseconds;
using std::chrono::duration_cast;
const auto duration = milliseconds(100);
const auto start = system_clock::now();
std::this_thread::sleep_for(duration);
const auto stop = system_clock::now();
const auto d_correct = duration_cast<nanoseconds>(duration).count();
const auto d_actual = duration_cast<nanoseconds>(stop - start).count();
std::cout << "Difference is " << d_actual << ", and it should be roughly " << d_correct << "\n";
}
Run Code Online (Sandbox Code Playgroud)
我们所期待的是一些东西
差异是100039989,它应该大约是100000000
看到这个演示,它的工作非常好.
但是,在我的机器上,根据Stack Overflow上的这个答案,安装了几个编译器似乎导致配置错误.
因此我尝试了建议的修复:设置正确LD_LIBRARY_PATH
.这些是我试过的输出组合(其中包括4.4和4.6 ...)
g++-4.7 …
Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
constexpr unsigned f(unsigned x)
{
while (x & 1) x *= 3;
return x;
}
int main()
{
char a[f(2)];
char b[f(1)];
}
Run Code Online (Sandbox Code Playgroud)
如果不明显:对于奇数整数x
,函数f
永远不会终止.
当我用coliru上的clang编译上面的程序时,b
似乎是一个VLA,但不是a
:
warning: variable length arrays are a C99 feature [-Wvla-extension]
char b[f(1)];
Run Code Online (Sandbox Code Playgroud)
是否存在明确定义的限制,编译器决定停止对常量表达式的求值?或者,对于符合标准的编译器来说,进入无限循环会是完美的吗?是否会f(1)
产生UB?
有没有人知道将数字均匀分配到一定数量的容器中的方法,确保容器的总值尽可能均匀?
编辑:"尽可能",我的意思是如果按X容器分配,每个容器的总数将接近总平均值.
现在我只是对数字数组进行排序(降序),然后将它们的值无关地分配到容器中.分配到三个容器中的一组1000,200,20,1000等于[2000],[200],[20].
我想做的是:
Example
Set of numbers: 10 30 503 23 1 85 355
If I were to distribute these into three containers I would just pick the highest first and then distribute them as I go, like this:
Cont 1 = 503
Cont 2 = 355
Cont 3 = 85 + 30 + 23 + 10 + 1
This will give the best possible distribution that you can get with the values provided.
Run Code Online (Sandbox Code Playgroud)
但我不知道在代码中表达这一点的简洁方法.
想法?
考虑以下课程:
class Foo
{
private:
void bar(const size_t);
public:
void foo();
};
Run Code Online (Sandbox Code Playgroud)
现在Foo::foo()
应该启动线程执行bar
,所以这是它的实现方式:
void Foo:foo()
{
auto handle = std::async(std::launch::async, &Foo::bar, this, 0);
handle.get();
}
Run Code Online (Sandbox Code Playgroud)
这与g ++ - 4.6.3完美配合,但与g ++ - 4.5.2无关,错误信息是
include/c ++/4.5.2/functional:180:9:错误:必须使用».«或» - > «使用_Tp = void(Foo ::*)(long unsigned int)调用»std :: declval中的指向成员函数,typename std :: add_rvalue_reference <_Tp> :: type = void( Foo :: &&)(long unsigned int)(...)«,例如»(... - > std :: declval with _Tp = void(Foo ::*)(long unsigned int),typename std :: add_rvalue_reference <_Tp> :: type …
我最近运行valgrind --tool=helgrind
了我的项目并收到了一条警告"可能的数据竞争",我认为这是一个问题.但是,即使是这个简单的测试程序也会导致以下消息:
#include <iostream>
#include <thread>
#include <future>
int main()
{
std::packaged_task<void()> task([]()
{
std::cout << "Hello\n"; // You can leave this out
});
auto future = task.get_future();
std::thread(std::move(task)).detach();
future.get();
}
Run Code Online (Sandbox Code Playgroud)
编译g++-4.9 -p -g -std=c++11 -pthread -O3 test.cpp
,输出valgrind --tool=helgrind ./a.out
是:
==12808== Helgrind, a thread error detector
==12808== Copyright (C) 2007-2013, and GNU GPL'd, by OpenWorks LLP et al.
==12808== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==12808== Command: ./a.out
==12808==
Hello …
Run Code Online (Sandbox Code Playgroud) 我有一个类库,我想将其发布为 nuget 包。它包含一些编译时必需的属性(分析器正常运行),但不需要传递地包含它,即<PrivateAssets>all</PrivateAssets>
应该在包引用上启用。我知道这可以通过 来实现<DevelopmentDependency>true</DevelopmentDependency>
,但是,这也设置了<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
,这不是我需要的。我需要将其设置为默认值<IncludeAssets>compile; runtime</IncludeAssets>
。
如何修改我的包以获得正确的默认值?
包定义的当前状态:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
<DevelopmentDependency>true</DevelopmentDependency>
<!--some more values like package id, version, etc.-->
</PropertyGroup>
</Project>
Run Code Online (Sandbox Code Playgroud)
安装时,这变成
<PackageReference Include="My.Package.Name" Version="1.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
Run Code Online (Sandbox Code Playgroud)
我希望它是
<PackageReference Include="My.Package.Name" Version="1.0.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>compile; runtime</IncludeAssets>
</PackageReference>
Run Code Online (Sandbox Code Playgroud)