Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/161.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何重写C++;代码(嵌套三元运算符)_C#_C++_C - Fatal编程技术网

C# 如何重写C++;代码(嵌套三元运算符)

C# 如何重写C++;代码(嵌套三元运算符),c#,c++,c,C#,C++,C,为了进行调试,我一直在查看其他人的代码,发现如下: !m_seedsfilter ? good=true : m_seedsfilter==1 ? good=newClusters(Sp) : good=newSeed(Sp); 这是什么意思?是否有一个自动工具可以将其转换为更易于理解的if/else语句?处理像这样复杂的控制结构有什么建议吗 编辑注:我将标题中的“不必要的复杂”改为“复杂”,因为这是一个意见问题。谢谢你迄今为止的所有答案。这样更好吗 !m_seedsfilter ? go

为了进行调试,我一直在查看其他人的代码,发现如下:

!m_seedsfilter ? good=true : m_seedsfilter==1 ? good=newClusters(Sp) : good=newSeed(Sp);  
这是什么意思?是否有一个自动工具可以将其转换为更易于理解的if/else语句?处理像这样复杂的控制结构有什么建议吗

编辑注:我将标题中的“不必要的复杂”改为“复杂”,因为这是一个意见问题。谢谢你迄今为止的所有答案。

这样更好吗

!m_seedsfilter ? good=true 
               : m_seedsfilter==1 ? good=newClusters(Sp) 
                                  : good=newSeed(Sp);  
我要补充一点,虽然理论上可以简化这个表达式(为什么?这太清楚了!),但得到的表达式可能不会在所有可能的情况下都是100%等价的。。。并显示两个表达式在C++中是否真的等价,这是一个非常非常非常复杂的问题…< /P> 我设计的退化示例()(注意它不是很退化…它只是基于一个小的编程错误)是基于考虑
good
a
bool
,创建两个类
UnixDateTime
SmallUnixDateTime
,使用
newClusters()
返回
SmallUnixDateTime
newSeed()
返回
UnixDateTime
。它们都应用于包含Unix日期时间,格式为从1970-01-01午夜开始的秒数
SmallUnixDateTime
使用
int
,而
UnixDateTime
使用
long
。两者都可以隐式转换为
bool
(如果它们的内部值是
!=0
,它们就会返回,这是“经典的”),但是
UnixDateTime
甚至可以隐式转换为
SmallUnixDateTime
(这是错误的,因为可能会丢失精度……这是一个小的编程错误)。转换失败时,返回设置为
0
SmallUnixDateTime
。在本例的代码中,始终存在一个转换:从
SmallUnixDateTime
bool
或从
UnixDateTime
bool

在这个类似但不同的例子中:

good = !m_seedsfilter ? true 
                      : m_seedsfilter==1 ? newClusters(Sp) 
                                         : newSeed(Sp);
有两种可能的路径:
SmallUnixDateTime
newClusters(Sp)
)转换为
bool
,或者
UnixDateTime
newSeed(Sp)
)首先转换为
SmallUnixDateTime
,然后转换为
bool
。很明显,这两个表达式并不相等


要使其工作(或“不工作”),
newSeed(Sp)
返回一个不能包含在
SmallUnixTime
std::numeric\u limits::max()+1LL
)中的值。

如果按以下方式重写,则编写的语句可以得到改进

good = m_seedsfilter==0 ? true :
       m_seedsfilter==1 ? newClusters(Sp) :
                          newSeed(Sp);
…但一般来说,你应该熟悉三元陈述。无论是最初发布的代码,还是xanatos的版本,还是我的版本,都没有本质上的邪恶。三元语句并不是邪恶的,它们是语言的一个基本特性,一旦你熟悉了它们,你会注意到像这样的代码(正如我所发布的,而不是你原来的帖子中所写的)实际上比一系列if-else语句更容易阅读。例如,在这段代码中,您可以简单地如下阅读此语句:“变量
good
等于……如果
m_seedsfilter==0
,则
true
,否则,如果
m_seedsfilter==1
,则
newClusters(Sp)
,否则,
newSeed(Sp)

请注意,我上面的版本避免了对变量
good
进行三次单独赋值,并明确说明语句的目标是为
good
赋值。同样,以这种方式编写,它清楚地表明,本质上这是一个“切换案例”构造,默认案例是
newSeed(Sp)

可能应该注意的是,我上面的重写只要是
操作符就可以了!()
对于
m_seedsfilter
类型,不重写。如果是,那么您必须使用它来保留原始版本的行为

good = !m_seedsfilter   ? true :
       m_seedsfilter==1 ? newClusters(Sp) :
                          newSeed(Sp);
…正如xanatos下面的评论所证明的,如果您的
newClusters()
newSeed()
方法返回的类型不同,并且如果这些类型是使用精心编制的无意义转换运算符编写的,那么您将不得不恢复到原始代码本身(虽然希望格式更好,就像在xanatos自己的帖子中一样)以忠实地复制与原始帖子完全相同的行为。但是在现实世界中,没有人会这样做,所以我上面的第一个版本应该可以


更新,原始帖子/答案发布两年半后: 有趣的是,@TimothyShields和我不断获得这方面的支持票,Tim的答案似乎始终保持在这个答案的支持票的50%左右,或多或少(截至本次更新,43对22)

我想我应该添加另一个例子,说明三元语句在使用得当时可以增加的清晰度。下面的例子是我为callstack使用率分析器(一个分析已编译C代码的工具,但该工具本身是用C#编写的)编写的代码的简短片段.所有三种变体实现完全相同的目标,至少就外部可见效果而言

1.没有三元运算符:

Console.Write(new string(' ', backtraceIndentLevel) + fcnName);
if (fcnInfo.callDepth == 0)
{
   Console.Write(" (leaf function");
}
else if (fcnInfo.callDepth == 1)
{
   Console.Write(" (calls 1 level deeper");
}
else
{
   Console.Write(" (calls " + fcnInfo.callDepth + " levels deeper");
}
Console.WriteLine(", max " + (newStackDepth + fcnInfo.callStackUsage) + " bytes)");
Console.Write(new string(' ', backtraceIndentLevel) + fcnName);
Console.Write((fcnInfo.callDepth == 0) ? (" (leaf function") :
              (fcnInfo.callDepth == 1) ? (" (calls 1 level deeper") :
                                         (" (calls " + fcnInfo.callDepth + " levels deeper"));
Console.WriteLine(", max " + (newStackDepth + fcnInfo.callStackUsage) + " bytes)");
Console.WriteLine(
   new string(' ', backtraceIndentLevel) + fcnName +
   ((fcnInfo.callDepth == 0) ? (" (leaf function") :
    (fcnInfo.callDepth == 1) ? (" (calls 1 level deeper") :
                               (" (calls " + fcnInfo.callDepth + " levels deeper")) +
   ", max " + (newStackDepth + fcnInfo.callStackUsage) + " bytes)");
string tempStr;
if (fcnInfo.callDepth == 0)
{
   tempStr = " (leaf function";
}
else if (fcnInfo.callDepth == 1)
{
   tempStr = " (calls 1 level deeper";
}
else
{
   tempStr = " (calls " + fcnInfo.callDepth + " levels deeper";
}
Console.WriteLine(new string(' ', backtraceIndentLevel) + fcnName + tempStr +
                  ", max " + (newStackDepth + fcnInfo.callStackUsage) + " bytes)");
2.使用三元运算符,分别调用Console.Write():

Console.Write(new string(' ', backtraceIndentLevel) + fcnName);
if (fcnInfo.callDepth == 0)
{
   Console.Write(" (leaf function");
}
else if (fcnInfo.callDepth == 1)
{
   Console.Write(" (calls 1 level deeper");
}
else
{
   Console.Write(" (calls " + fcnInfo.callDepth + " levels deeper");
}
Console.WriteLine(", max " + (newStackDepth + fcnInfo.callStackUsage) + " bytes)");
Console.Write(new string(' ', backtraceIndentLevel) + fcnName);
Console.Write((fcnInfo.callDepth == 0) ? (" (leaf function") :
              (fcnInfo.callDepth == 1) ? (" (calls 1 level deeper") :
                                         (" (calls " + fcnInfo.callDepth + " levels deeper"));
Console.WriteLine(", max " + (newStackDepth + fcnInfo.callStackUsage) + " bytes)");
Console.WriteLine(
   new string(' ', backtraceIndentLevel) + fcnName +
   ((fcnInfo.callDepth == 0) ? (" (leaf function") :
    (fcnInfo.callDepth == 1) ? (" (calls 1 level deeper") :
                               (" (calls " + fcnInfo.callDepth + " levels deeper")) +
   ", max " + (newStackDepth + fcnInfo.callStackUsage) + " bytes)");
string tempStr;
if (fcnInfo.callDepth == 0)
{
   tempStr = " (leaf function";
}
else if (fcnInfo.callDepth == 1)
{
   tempStr = " (calls 1 level deeper";
}
else
{
   tempStr = " (calls " + fcnInfo.callDepth + " levels deeper";
}
Console.WriteLine(new string(' ', backtraceIndentLevel) + fcnName + tempStr +
                  ", max " + (newStackDepth + fcnInfo.callStackUsage) + " bytes)");
3.使用三元运算符,折叠为对Console.Write()的单个调用:

Console.Write(new string(' ', backtraceIndentLevel) + fcnName);
if (fcnInfo.callDepth == 0)
{
   Console.Write(" (leaf function");
}
else if (fcnInfo.callDepth == 1)
{
   Console.Write(" (calls 1 level deeper");
}
else
{
   Console.Write(" (calls " + fcnInfo.callDepth + " levels deeper");
}
Console.WriteLine(", max " + (newStackDepth + fcnInfo.callStackUsage) + " bytes)");
Console.Write(new string(' ', backtraceIndentLevel) + fcnName);
Console.Write((fcnInfo.callDepth == 0) ? (" (leaf function") :
              (fcnInfo.callDepth == 1) ? (" (calls 1 level deeper") :
                                         (" (calls " + fcnInfo.callDepth + " levels deeper"));
Console.WriteLine(", max " + (newStackDepth + fcnInfo.callStackUsage) + " bytes)");
Console.WriteLine(
   new string(' ', backtraceIndentLevel) + fcnName +
   ((fcnInfo.callDepth == 0) ? (" (leaf function") :
    (fcnInfo.callDepth == 1) ? (" (calls 1 level deeper") :
                               (" (calls " + fcnInfo.callDepth + " levels deeper")) +
   ", max " + (newStackDepth + fcnInfo.callStackUsage) + " bytes)");
string tempStr;
if (fcnInfo.callDepth == 0)
{
   tempStr = " (leaf function";
}
else if (fcnInfo.callDepth == 1)
{
   tempStr = " (calls 1 level deeper";
}
else
{
   tempStr = " (calls " + fcnInfo.callDepth + " levels deeper";
}
Console.WriteLine(new string(' ', backtraceIndentLevel) + fcnName + tempStr +
                  ", max " + (newStackDepth + fcnInfo.callStackUsage) + " bytes)");
有人可能会说,上面三个例子之间的区别很小,既然它很小,为什么不选择更简单的(第一个)变体呢?这都是为了简洁;用“尽可能少的话”表达一个想法这样,当我说到点子的结尾时,听者/读者仍能记住点子的开头。当我和小孩子说话时,我会用简单、简短的句子

    good = !m_seedsfilter ? true : 
                            ( m_seedsfilter == 1 ? newClusters(SP) : 
                                                   newSeed(SP) );
!m_seedsfilter ? good=true : m_seedsfilter==1 ? good=newClusters(Sp) : good=newSeed(Sp);
if (!m_seedsfilter)
{
     good = true;
}
else
{
     if (m_seedsfilter == 1)
     {
          good = newClusters(Sp);
     }
     else
     {
          good = new Seed(Sp);
     }
}