我被 MSVC 意外的 C++ 函数匹配所困扰。我可以将其简化为以下测试用例:
#include <iostream>
enum Code { aaa, bbb };
struct MyVal {
Code c;
MyVal(Code c): c(c) { }
};
void test(int i, MyVal val) {
std::cout << "case " << i << ": value " << val.c << std::endl;
}
void test(int i, double* f) {
std::cout << "case " << i << ": WRONG" << std::endl;
}
const Code v1 = aaa;
Code v2 = aaa;
const Code v3 = bbb;
int main() {
const Code w1 = aaa;
Code w2 = aaa;
const Code w3 = bbb;
test(1, v1); // unexpected MSVC WRONG
test(2, v2);
test(3, v3);
test(4, aaa);
test(5, w1); // unexpected MSVC WRONG
test(6, w2);
test(7, w3);
return 0;
}
我预计 test 的所有 7 次调用都将匹配第一个重载,并且 GCC ( live example ) 和 Clang ( live example ) 按预期匹配:
case 1: value 0
case 2: value 0
case 3: value 1
case 4: value 0
case 5: value 0
case 6: value 0
case 7: value 1
但 MSVC ( live example ) 将情况 1 和 5 与“错误”重载相匹配(我在 MSVC 2013 和 2015 中发现了这种行为):
case 1: WRONG
case 2: value 0
case 3: value 1
case 4: value 0
case 5: WRONG
case 6: value 0
case 7: value 1
对于具有(意外)值 0 的 const 枚举变量,似乎 MSVC 更喜欢转换为指针。我本以为这是文字 0 的行为,但不是枚举变量。
我的问题:MSVC 行为是否符合标准? (可能适用于旧版本的 C++?)如果不是,这是已知的扩展或错误吗?
最佳答案
你没有说出任何标准,但让我们看看有什么区别:
[C++11: 4.10/1]:A null pointer constant is an integral constant expression (5.19) prvalue of integer type that evaluates to zero or a prvalue of typestd::nullptr_t. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of object pointer or function pointer type. Such a conversion is called a null pointer conversion. Two null pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification. [..]
[C++11: 5.19/3]:A literal constant expression is a prvalue core constant expression of literal type, but not pointer type. An integral constant expression is a literal constant expression of integral or unscoped enumeration type. [..]
和:
[C++03: 4.10/1]:A null pointer constant is an integral constant expression (5.19) rvalue of integer type that evaluates to zero. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type and is distinguishable from every other value of pointer to object or pointer to function type. Two null pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification conversion (4.4).
[C++03: 5.19/2]:Other expressions are considered constant-expressions only for the purpose of non-local static object initialization (3.6.2). Such constant expressions shall evaluate to one of the following:
- a null pointer value (4.10),
- a null member pointer value (4.11),
- an arithmetic constant expression,
- an address constant expression,
- a reference constant expression,
- an address constant expression for a complete object type, plus or minus an integral constant expression, or
- a pointer to member constant expression.
这里的关键是标准语言在 C++03 和 C++11 之间发生了变化,后者引入了这种形式的空指针常量必须是文字的要求。
(它们实际上始终需要是常量并评估为 0,因此您可以删除 v2、v3、w2 和 w3 来自你的测试用例。)
空指针常量可以比通过用户定义的转换更容易地转换为 double*,所以……
我相信 MSVS 正在实现 C++03 规则。
有趣的是,如果我将 GCC 置于 C++03 模式,它的行为不会改变,这在技术上是不兼容的。我怀疑语言的变化源于当时常见实现的行为,而不是相反。我可以看到一些 evidence that GCC was [allegedly] non-conforming in this regard as early as 2004 ,所以也可能只是标准措辞的改变偶然地取消了 GCC 错误。
关于c++ - 与 const 枚举值 0 匹配的 MSVC 函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41058178/
我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server
在我的应用程序中,我需要能够找到所有数字子字符串,然后扫描每个子字符串,找到第一个匹配范围(例如5到15之间)的子字符串,并将该实例替换为另一个字符串“X”。我的测试字符串s="1foo100bar10gee1"我的初始模式是1个或多个数字的任何字符串,例如,re=Regexp.new(/\d+/)matches=s.scan(re)给出["1","100","10","1"]如果我想用“X”替换第N个匹配项,并且只替换第N个匹配项,我该怎么做?例如,如果我想替换第三个匹配项“10”(匹配项[2]),我不能只说s[matches[2]]="X"因为它做了两次替换“1fooX0barXg
如何匹配未被反斜杠转义的平衡定界符对(其本身未被反斜杠转义)(无需考虑嵌套)?例如对于反引号,我试过了,但是转义的反引号没有像转义那样工作。regex=/(?!$1:"how\\"#expected"how\\`are"上面的正则表达式不考虑由反斜杠转义并位于反引号前面的反斜杠,但我愿意考虑。StackOverflow如何做到这一点?这样做的目的并不复杂。我有文档文本,其中包括内联代码的反引号,就像StackOverflow一样,我想在HTML文件中显示它,内联代码用一些spanMaterial装饰。不会有嵌套,但转义反引号或转义反斜杠可能出现在任何地方。
我想在一个没有Sass引擎的类中使用Sass颜色函数。我已经在项目中使用了sassgem,所以我认为搭载会像以下一样简单:classRectangleincludeSass::Script::FunctionsdefcolorSass::Script::Color.new([0x82,0x39,0x06])enddefrender#hamlengineexecutedwithcontextofself#sothatwithintemlateicouldcall#%stop{offset:'0%',stop:{color:lighten(color)}}endend更新:参见上面的#re
我正在尝试用ruby中的gsub函数替换字符串中的某些单词,但有时效果很好,在某些情况下会出现此错误?这种格式有什么问题吗NoMethodError(undefinedmethod`gsub!'fornil:NilClass):模型.rbclassTest"replacethisID1",WAY=>"replacethisID2andID3",DELTA=>"replacethisID4"}end另一个模型.rbclassCheck 最佳答案 啊,我找到了!gsub!是一个非常奇怪的方法。首先,它替换了字符串,所以它实际上修改了
我有一些代码在几个不同的位置之一运行:作为具有调试输出的命令行工具,作为不接受任何输出的更大程序的一部分,以及在Rails环境中。有时我需要根据代码的位置对代码进行细微的更改,我意识到以下样式似乎可行:print"Testingnestedfunctionsdefined\n"CLI=trueifCLIdeftest_printprint"CommandLineVersion\n"endelsedeftest_printprint"ReleaseVersion\n"endendtest_print()这导致:TestingnestedfunctionsdefinedCommandLin
我有一个驼峰式字符串,例如:JustAString。我想按照以下规则形成长度为4的字符串:抓取所有大写字母;如果超过4个大写字母,只保留前4个;如果少于4个大写字母,则将最后大写字母后的字母大写并添加字母,直到长度变为4。以下是可能发生的3种情况:ThisIsMyString将产生TIMS(大写字母);ThisIsOneVeryLongString将产生TIOV(前4个大写字母);MyString将生成MSTR(大写字母+tr大写)。我设法用这个片段解决了前两种情况:str.scan(/[A-Z]/).first(4).join但是,我不太确定如何最好地修改上面的代码片段以处理最后一种
我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle
如何在Ruby中按名称传递函数?(我使用Ruby才几个小时,所以我还在想办法。)nums=[1,2,3,4]#Thisworks,butismoreverbosethanI'dlikenums.eachdo|i|putsiend#InJS,Icouldjustdosomethinglike:#nums.forEach(console.log)#InF#,itwouldbesomethinglike:#List.iternums(printf"%A")#InRuby,IwishIcoulddosomethinglike:nums.eachputs在Ruby中能不能做到类似的简洁?我可以只
如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是: