这基本上是这个问题的延续.到目前为止看起来如果我有这样的函数:
void SecureZeroMemory( void* ptr, size_t cnt )
{
volatile char *vptr = (volatile char *)ptr;
while (cnt) {
*vptr = 0;
vptr++;
cnt--;
}
}
Run Code Online (Sandbox Code Playgroud)
并称之为:
{
char buffer[size];
SecureZeroMemory( buffer, size );
}
Run Code Online (Sandbox Code Playgroud)
那么因为buffer没有声明volatile,所以使用指向volatile的指针并不重要 - 数据本身不是易失性的,所以写入变量不构成可观察的行为(1.9/6),并允许编译器优化它们.
然而,最近我发现一个声明,它只是重要的指针声明.具体来说,C++ 03 5.3.1/1描述了间接(*),如下所示:
一元*运算符执行间接[...]如果表达式的类型是"指向T的指针",则结果的类型为"T".
所以声称是因为在volatile char*我们的get volatile char和write 上使用间接确实构成了可观察的行为,并且不再重要的是如何声明实际数据.
C++ 03 5.3.1/1间接描述是否真的保证使用volatile T*上面示例中的指针覆盖内存构成可观察行为并且不允许进行优化?
c++ compiler-construction optimization indirection compiler-optimization
我很难理解何时以及为什么在推送Scalar后会影响推送的容器所持有的价值。我将在两个风格化的示例中尝试说明我在更复杂的上下文中遇到的问题。
*示例1 *在第一个示例中,标量作为a的一部分$i被推到数组@b上List。推送之后,使用$i++指令在for循环的后续迭代中显式更新标量持有的值。这些更新会影响数组中的值@b:在for循环的末尾,@b[0;0]等于3,不再等于2。
my @b;
my $i=0;
for 1..3 -> $x {
$i++;
say 'Loose var $i: ', $i.VAR.WHICH, " ", $i.VAR.WHERE;
if $x == 2 {
@b.push(($i,1));
say 'Pushed $i : ', @b[0;0].VAR.WHICH, " ", @b[0;0].VAR.WHERE;
}
}
say "Post for-loop";
say "Array : ", @b;
say 'Pushed $i : ', @b[0;0].VAR.WHICH, " ", @b[0;0].VAR.WHERE;
Run Code Online (Sandbox Code Playgroud)
输出示例1:
Loose var $i: Scalar|94884317665520 …Run Code Online (Sandbox Code Playgroud) 我正在尝试创建一个迭代器类作为列表类的成员类,并尝试重载间接运算符(*)以访问它指向的列表:
template<class T>
T list<T>::iterator::operator*(iterator& iter)
{
return ((iter.lstptr)->current)->data;
}
Run Code Online (Sandbox Code Playgroud)
where lstptr是指向列表current的指针,是指向节点类的指针,节点类包含data类型的数据成员T.
Iterator声明如下:
template<class T>
class list
{
public:
class iterator;
};
template<class T>
class list<T>::iterator
{
//stuff
};
Run Code Online (Sandbox Code Playgroud)
我能够编译重载运算符*的函数定义,但是当我尝试做类似的事情时:
list<int> lst1;
lst1.add(6);
list<int>::iterator IT;
IT = lst1;
//everything above this point compiles fine
int a = *IT; //error here (line fourteen)
Run Code Online (Sandbox Code Playgroud)
我得到的错误<1>表示我使用的是非法间接,而<2>表示它无法从list :: iterator转换为int.这两个错误都发生在第14行.
有人知道我做错了什么以及如何正确地重载间接操作符?
注意:如果你需要查看更多代码,请告诉我哪个部分,因为我不想把整个代码放在这里,因为它有205行,而其中204行(我认为)没有任何错误.
是否可以通过将两个字符串连接在一起形成名称来设置变量?
如果可能的话,我想根据用户点击的对象的类名确定要设置的变量.我知道我可以硬编码一堆if/else if语句,但如果我可以间接引用变量,那将会非常酷.我在想这样的事情:
var owner_read;
var group_read;
function setVariableIndirectly(object){
var second = object.className; // returns "read"
var first = object.parentElement.className; // returns "group"
first + "_" + second = "set this as the new variable";
}
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点?
编辑:
这是数据来自的html.
<p class="owner">
<span class="read" onclick="permissionClick(this)">r</span>
<span class="write" onclick="permissionClick(this)">w</span>
<span class="execute" onclick="permissionClick(this)">x</span>
</p>
Run Code Online (Sandbox Code Playgroud) 我正在寻找一个一元函子,它将取消引用它的参数并返回结果.当然我可以写一个,它似乎应该已经存在.
所以给出代码:
const auto vals = { 0, 1, 2, 3 };
vector<const int*> test(size(vals), nullptr);
iota(begin(test), end(test), data(vals));
transform(cbegin(test), cend(test), ostream_iterator<int>(cout, " "), [](const auto& i){ return *i; });
Run Code Online (Sandbox Code Playgroud)
我希望有一个我可以用而不是lambda的仿函数.这样的事情存在,还是我需要使用lambda?
我的问题很简单.我有一个类模板,它包含一个指向动态分配类型的指针.我想重载间接运算符,以便引用带有 - >运算符的类模板实例,我被重定向,就像我直接使用包含在其中的指针一样.
template<class T>
class MyClass
{
T *ptr;
...
// created dynamic resource for ptr in the constructor
};
Run Code Online (Sandbox Code Playgroud)
创建某种类型的myclass:
MyClass<SomeObject> instance;
Run Code Online (Sandbox Code Playgroud)
所以我想要的不是必须键入:
instance.ptr->someMemberMethod();
Run Code Online (Sandbox Code Playgroud)
我只需输入:
intance->someMemberMethod();
Run Code Online (Sandbox Code Playgroud)
即使你instance不是一个指针,它的行为就像指针所instance包含的一样.如何通过超载运营商来弥补这一差距?
我正在阅读c#数组,所以我的问题最初是在数组上.
声明数组实际意味着什么?我知道你声明了一个类型为array的变量.当我有以下内容时,实际发生了什么?
int[] values;
Run Code Online (Sandbox Code Playgroud)
声明时它是否在记忆中?如果不是那么它在哪里?阵列实际上是在这里创建的吗?
然后我去实例化一个数组并用一些值初始化它,如:
int[] values = new int[] { 1, 2, 3 };
Run Code Online (Sandbox Code Playgroud)
这实际上是现在创建阵列吗?我已阅读,创建数组在声明时,别人说自己被实例化时创建数组.我想让我的术语正确.
整数变量也是如此.如果我有:
int value;
Run Code Online (Sandbox Code Playgroud)
和
int value = 1;
Run Code Online (Sandbox Code Playgroud)
什么时候创建int?什么时候加入内存?
抱歉愚蠢的问题.我理解这个概念,但想知道阵列的幕后technicallity.
我试图找出一种易于阅读和理解的习惯用法,用于评估名称存储在变量中的环境变量的值:
$varName='TEMP'
Run Code Online (Sandbox Code Playgroud)
我想出了
$val = invoke-expression "`$env:$varName"
Run Code Online (Sandbox Code Playgroud)
我想知道是否有更切题的替代方案。
编辑:这已被确认是一个错误并将被修复:https : //lists.gnu.org/archive/html/bug-bash/2018-03/msg00055.html
所以我在搞砸 bash 的间接功能,namerefs。我以为我已经掌握了它的窍门,但是当我试图弄清楚如何将 namerefs 转换为常规变量时,我遇到了一些让我困惑的事情。
这是来自man bash:的相关段落:
declare -n为每个名称指定 nameref 属性,使其成为对另一个变量的名称引用。另一个变量由 name 的值定义。除了使用或更改 -n 属性本身的那些引用、赋值和属性修改之外,所有对 name 的引用、赋值和属性修改都是在 name 值引用的变量上执行的。
因此,假设您想取消设置 nameref——不是它指向的变量,而是变量本身。您不能只说unset foo,因为这实际上会取消设置foo指向的任何内容;相反,您必须将其设为常规变量,然后取消设置:
$ declare -p
$ foo=bar; bar='hello world'
$ declare -p
declare -- foo="bar"
declare -- bar="hello world"
$ declare -n foo; declare -p # 'foo' is now a nameref
declare -n foo="bar"
declare -- bar="hello world"
$ declare +n foo; declare -p # …Run Code Online (Sandbox Code Playgroud) 根据这个答案,我可以检查数组是否是索引的或关联的,如下所示:
$ declare -a a
$ declare -A b
$ echo ${a@a}
a
$ echo ${b@a}
A
Run Code Online (Sandbox Code Playgroud)
然而,如果我使用间接扩展,它就不起作用:
$ var=a
$ echo ${!var@a}
$ var=b
$ echo ${!var@a}
$
Run Code Online (Sandbox Code Playgroud)
然而,如果我初始化数组,它现在又可以工作了:
$ a=()
$ b=()
$ var=a
$ echo ${!var@a}
a
$ var=b
$ echo ${!var@a}
A
$
Run Code Online (Sandbox Code Playgroud)
这是预期行为还是 Bash 错误?
$ bash --version
GNU bash, version 5.1.16(1)-release (x86_64-pc-linux-gnu)
[...]
Run Code Online (Sandbox Code Playgroud) indirection ×10
c++ ×4
bash ×2
.net ×1
c# ×1
for-loop ×1
functor ×1
javascript ×1
optimization ×1
perl6 ×1
powershell ×1
raku ×1
unset ×1
variables ×1