假设您有以下定义:
struct X
{
char a, b;
};
X x;
Run Code Online (Sandbox Code Playgroud)
现在假设您有两个线程,其中一个读取和写入x.a
但从不访问,x.b
而另一个读取和写入x.b
但从不访问x.a
.两个线程都不使用任何锁或其他同步原语.这可以保证在C++ 11中有效吗?或者它是否算作访问同一个对象,因此需要锁定?
我正在考虑一个与完美转发有一些相似性的问题,但是函数参数没有传递给被调用函数,而是返回.这就是我称之为"完美传递"的原因.
问题如下:
假设我们有一个函数,它通过引用获取一个对象(可能还有一些额外的参数),修改该对象,并返回修改后的对象.这些函数的最着名的例子可能是operator<<
和operator>>
iostreams一样.
让我们以iostream为例,因为它可以很好地展示我所追求的东西.例如,有时人们喜欢做的一件事是:
std::string s = (std::ostringstream() << foo << bar << baz).str();
Run Code Online (Sandbox Code Playgroud)
当然这不起作用,原因有两个:
std::ostringstream()
是一个右值,但是operator<<
将左值作为第一个参数
operator<<
返回一个ostream&
(以及,至少为标准的人实际上是一个basic_ostream<CharT, Traits>&
其中CharT
与Traits
从第一自变量推导出).
因此,我们假设我们要设计插入运算符,以便上述工作(您显然不能对现有运算符执行此操作,但您可以为自己的类执行此操作).显然,该解决方案应具有以下特征:
第一个参数可以接受左值或右值.
返回类型应该与传入的类型相同.但是它当然应该只接受ostreams(即从实例化派生的类basic_ostream
).
虽然在这个特定用例中不需要,但我想添加第三个要求:
这个额外的规则是你可以从通过函数传递的rvalue中移动构造(我不知道C++ 11流是否可移动构造,但它是一个更通用的方案,流如同方便的例子).
很明显,在C++ 03中,并不能满足这些要求.但是,在C++ 11中,我们有rvalue引用,这应该可以实现.
这是我的尝试:
#include <iostream>
#include <sstream>
#include <string>
template<typename Ostream> struct is_ostream
{
typedef typename std::remove_reference<Ostream>::type candidate;
typedef typename candidate::char_type char_type;
typedef typename candidate::traits_type traits_type;
typedef std::basic_ostream<char_type, traits_type> basic_ostream;
static const bool value = std::is_base_of<basic_ostream, …
Run Code Online (Sandbox Code Playgroud) 从istream中读取的惯用循环是
while (thestream >> value)
{
// do something with value
}
Run Code Online (Sandbox Code Playgroud)
现在这个循环有一个问题:它不会区分循环是由于文件结束还是由于错误而终止.例如,采取以下测试程序:
#include <iostream>
#include <sstream>
void readbools(std::istream& is)
{
bool b;
while (is >> b)
{
std::cout << (b ? "T" : "F");
}
std::cout << " - " << is.good() << is.eof() << is.fail() << is.bad() << "\n";
}
void testread(std::string s)
{
std::istringstream is(s);
is >> std::boolalpha;
readbools(is);
}
int main()
{
testread("true false");
testread("true false tr");
}
Run Code Online (Sandbox Code Playgroud)
第一次调用testread
包含两个有效的bool,因此不是错误.第二个呼叫以第三个不完整的bool结束,因此是一个错误.然而,两者的行为是相同的.在第一种情况下,读取布尔值失败,因为没有,而在第二种情况下,它失败,因为它是不完整的,并且在两种情况下都会命中EOF.实际上,上面的程序输出两次相同的行:
TF - 0110
TF - …
Run Code Online (Sandbox Code Playgroud) 在C++中,我们可以and
为for &&
,or
for ||
,bitand
for &
和bitor
for 编写|
.
现在我不知道是否and
和bitand
是唯一有效,其中的经营者是指,或者也可以在那里引用的定义(G ++ 4.6.3接受bitand
的引用-右值引用似乎并没有在该版本中得到支持-但当然这可能只是编译器不抓住错误).
简而言之:以下代码是否有效C++?
int and x = 3;
int a;
int bitand y = a;
Run Code Online (Sandbox Code Playgroud)
当然我永远不会写这样的代码(除非参与混淆的代码竞赛),但它实际上是否有效?
我想编写一个函数模板,apply
它接收一些函数f
,一个整数i
和一个参数包.apply
需要解压缩参数并应用于f
它们,除了i
th参数,pi
.因为pi
,它需要g
在将其作为参数传递之前调用其他函数f
.
看来我需要一种方法将参数包分为左侧,第i
th个参数和右侧.这可能吗?在代码中:
template<int i, typename Function, typename... Parms>
void apply(Function f, Parms... parms)
{
auto lhs = // what goes here?
auto pi = // what goes here?
auto rhs = // what goes here?
f(lhs..., g(pi), rhs...);
}
Run Code Online (Sandbox Code Playgroud) 这个问题来自于源于这个答案的讨论.
简而言之:答案的作者(0x499602D2)声称(正确地,正如我现在所知),当不跳过空格,但下一个字符是空格时,除字符外的所有提取都将失败.
我在基础上质疑这一点,我认为提取a string
不应该失败,因为流包含一个由开头的空白字符分隔的空字符串.
无论字符串中的任何位置是否存在空字符串,例如在字符串a
和b
字符串之间"ab"
(我说是,0x499602D2表示否),这就形成了一般讨论.0x499602D2建议我把它放在一个问题中,所以在这里我做.
我从该主题(包括聊天部分)复制我的主要论点:
让我们首先看一下空字符串的常量.在C和C++中,内容在开头和结尾用引号分隔.那么空字符串是什么样的?你知道的:
""
.你看,在初始引用(分隔符)之后直接跟随最终引用(分隔符).空字符串位于两个引号之间,它们直接相互跟随,因为空字符串没有字符.另请参阅C表示.这是字符序列,后跟分隔符'\ 0'.那么空字符串的表示是什么?好吧,空字符串的字符后跟分隔符.这意味着,第一个字符是分隔符(即,与流情况完全相同).现在考虑字符串的连接,例如第一个字符串是"a"
,第二个字符串是空的,第三个字符串是"b"
.那么连接是什么?好吧,"ab"
.很明显,在a
和b
in 之间有一个空字符串"ab"
(我们明确地把它放在那里!).当然,在之前a
和之后也是如此b
.也就是说,字符串的任何两个字符之间都有一个空字符串(或两个或一百万个).空字符串没有字符,连续字符之间没有字符.因此,在两个字符之间有一个空字符串.另请参阅我之前给出的其他论点.另外,考虑与空字符串匹配的正则表达式:它们也匹配到处.例如,
/ab*c/
匹配"ac"
因为b*
匹配a
和之间的空字符串c
在分隔符(空格)之前有一个空字符串(即没有字符),就像在空字符串的C表示中一样,
\0
分隔符之前没有字符.另请注意,readline
对\n
分隔符的作用也相同:如果\n
立即执行,则不会失败但会给出一个空字符串.
我觉得无法在讨论中找出0x499602D2的主要论点,所以我不会试图避免在选择中无意中不公平.您应该能够在评论中看到它们(可能还有聊天室 - 我不知道每个人都可以访问它们).@ 0x499602D2:如果需要,您也可以在本段后面添加主要参数.
与此相关的实际问题是:如果在分隔符之前没有字符(如operator>>
字符串那样),那么设计良好的字符串提取函数是否会失败,或者成功并返回空字符串(如同readline
)?
你知道是否有可能以某种方式生成一个具有特定分支因子的随机树图?我不希望它是一棵k-ary树.
如果我可以定义分支因子和最大深度,那也是很好的.我想随机生成一堆树枝,它们的分枝因子和深度都不同.
随机整数输入的TreePlot返回几乎我想要的东西:
TreePlot[RandomInteger[#] -> # + 1 & /@ Range[0, 100]]
Run Code Online (Sandbox Code Playgroud)
但我无法弄清楚如何获得具有特定分支因子的树.
谢谢!
在C++(和C)中,我们有一个#pragma
基本上具有实现定义效果的指令.但是,该指令可能有什么限制吗?(请注意,我在询问标准允许的内容,而不是真正的编译器实际执行的内容.)
我肯定#pragma
可以这样做:
我猜是允许的,但不确定:
允许编译器接受其他非法代码而不发出诊断(例如,编译器可能决定支持新的内置类型long long long
,但使用该代码的任何代码都必须发出诊断;然后可以使用例如#pragma long long long
.
允许编译器拒绝其他合法代码,例如可能存在#pragma strict
导致编译器将某些库函数和/或被认为不安全的语言结构的使用标记为错误的错误.
我实际上怀疑是允许的,但我也不确定:
for
条件是后置条件(如do
... while
)是一个好主意,并定义#pragma for postcondion
为相应地切换其含义for
.我怀疑后者的原因是允许编译器忽略它无法识别的任何编译指示,因此编译指示语义的改变会导致同一程序在不同的编译器上具有不同的语义.
但是,标准实际允许什么?是否有允许的内容,但上面列表中没有涵盖哪些内容?
以下代码使用gcc 4.8.0(mingw-w64)失败,其中-O2 -std = c ++ 11 -frtti -fexceptions -mthreads
#include <string>
class Param
{
public:
Param() : data(new std::string) { }
Param(const std::string & other) : data(new std::string(other)) { }
Param(const Param & other) : data(new std::string(*other.data)) { }
Param & operator=(const Param & other) {
*data = *other.data; return *this;
}
~Param() {
delete data;
}
Param & operator=(Param &&) = delete;
private:
std::string * data;
};
int main()
{
Param param;
param = Param("hop");
return 0;
} …
Run Code Online (Sandbox Code Playgroud) 鉴于以下代码,
my $string = "foo";
my $regex = s/foo/bar/;
$string =~ $regex;
print $string, "\n";
Run Code Online (Sandbox Code Playgroud)
我本来期望输出是bar
,但它是foo
.为什么会这样,我该如何解决这个问题呢?
请注意,在我的实际情况中,正则表达式更复杂,我实际上想要将它们中的几个存储在哈希中(所以我可以编写类似的东西$string =~ $rules{$key}
).
大家好,我正在为学校制作一个基于文本的小冒险游戏,我想知道你是否可以将Unicode添加到C++.现在我添加了这个:Д但是当我调试我的游戏时它只是一个"?" 而不是"Д".我正在使用输出文本的iostream"cout"方法.我需要包含一些东西吗?我使用Visual Studio Express 2012.
这就是我打字的方式Д:
cout << "? |" << endl; //It's a part of the map
Run Code Online (Sandbox Code Playgroud)