问题:
是否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 ++语言功能的标准建议,可以让我取代它(感谢Yakk):
template<class... ARGS>
void bar(const ARGS& ... args) {
auto t = { (foo(args),0)... };
(void) t; //<- prevent warning about unused variable
}
Run Code Online (Sandbox Code Playgroud)
像这样更自然:
template<class... ARGS>
void bar(const ARGS& ... args) {
foo(args)...;
}
Run Code Online (Sandbox Code Playgroud)
foo 例如函数,函数模板和/或它们的重载集合,它们的返回类型可能是无效的(或者通常我不关心)。
顺便说一句,如果有人知道用c ++ 14编写的更简洁的方法,可以随意分享,但是我认为,这个问题已经解决了
我想编写一个c ++矩阵操作代码,某些函数的某些操作是相同的.我想知道是否有一些方法可以合并它们?例如:
void add1(vector<vector<double> > &m){
for(int i = 0; i < m.size(); ++i){
for(int j = 0; j < m[i].size(); ++j){
m[i][j] += 1.0;
}
}
}
void minus1(vector<vector<double> > &m){
for(int i = 0; i < m.size(); ++i){
for(int j = 0; j < m[i].size(); ++j){
m[i][j] -= 1.0;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这两段代码几乎相同.如何避免重写两次?是否有类似模板的东西可以自动生成代码?
我的一个朋友把他的程序发给我。他使用“stod”函数将字符串转换为双精度。还有其他可能性做这样的事情吗?
我的编译器显示错误“stod 未在此范围内声明”
我已包含#include <string> #include <cstdlib>但没有任何改变。
我的编译器不使用 C++11 功能。顺便说一句,该程序是作为学校项目编写的,没有使用 C++11 的目的。
cmake 中有没有办法找到定义目标的 CMakeLists.txt 文件的源目录?
类似的东西:
if (TARGET Foo)
message("Library Foo was alread built in ${LOCATION_OF_FOOS_CMAKE}")
else()
add_library(Foo ...)
endif()
Run Code Online (Sandbox Code Playgroud)
编辑:
不幸的是,我的 cmake 脚本必须在默认的 ubuntu 14.04 安装上工作。所以我仅限于cmake 2.8
我只是使用编译C/C++代码__transaction_atomic但发生编译错误
[Error] __transaction_atomic' without transactional memory support enabled 代码是:
#include <stdio.h>
int main()
{
int i = 0;
__transaction_atomic
{
i++;
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
怎么搞清楚?我的编译器是GCC 4.9
TL; DR:
我有一个使用boost的asio库的程序.在Win10上使用MSVC++(VS2015 Update 3)和在Ubuntu 14.04上使用g ++ 4.8进行编译时,它可以完美运行,但我也想使用随新版Visual Studio一起提供的clang前端(我相信自更新1以来) .
我的初始命令行选项(从项目属性页面复制)看起来像这样:
-fpic"stdafx.h" - std = c ++ 1y -fstack-protector"Clang \" - fno-strict-aliasing -ffunction-sections -g2 -gdwarf-2 -O0 -x c ++ - header -D"_WINSOCK_DEPRECATED_NO_WARNINGS" -D"NOMINMAX"-frtti -fomit-frame-pointer -fdata-sections -fno-ms-compatibility -std = c11 -fexceptions -o"Clang \%(filename).obj"-fms-extensions -fno-short-枚举
这给了我以下错误:
void __cdecl boost::detail::atomic_increment(struct __clang::_Atomic<int> *)': Unexpected atomic instruction -- use Windows interlock intrinsics
Run Code Online (Sandbox Code Playgroud)
显然,使用clang/c2版本不支持的clang/gcc内在函数而不是使用在使用VC++编译时使用的特定于Windows的内在函数会增加疲劳.我玩了不同的编译器选项,似乎唯一有效的是取消定义__clang__预处理器符号(在命令行中添加以下选项):
-U "__clang__"
Run Code Online (Sandbox Code Playgroud)
这摆脱了原子错误,但现在我得到多页错误消息似乎与一些boost mpl宏有关.以下是前几行:
1> In file included from main.cpp:1:
1> In file …Run Code Online (Sandbox Code Playgroud) 我想创建一个新库,并希望确保我不会重用已被其他库使用的命名空间.命名空间我主要是指一个c ++命名空间,但理想情况下也应该避免像gnu科学库和指南支持库之间的首字母缩略词冲突.
确定命名空间是否已被使用的合理方法是什么(除了谷歌搜索"c ++")?
编辑:
澄清:我知道无法确定我的命名空间名称是唯一的,甚至更少它将保持唯一.我正在寻找的是提示,以尽量减少与某些环境中的事实标准的常用库和/或库发生冲突的可能性(例如,我对mac/ios/android特定库一无所知).
是的,我可以使用,my_ridiculously_long_but_unique_namespace_name_xy5md4但如果你想在头文件中使用它,这是非常实用的.